blob: b022154ea91754d4f4607bf6c2cb1d4d6fe6215e [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;
Santos Cordon5c6fa952014-07-20 17:47:12 -070021import android.annotation.SdkConstant;
Tyler Gunn5567d742019-10-31 13:04:37 -070022import android.annotation.SystemApi;
Hall Liueb7c9ea2021-03-09 20:24:50 -080023import android.annotation.TestApi;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070024import android.app.Service;
Santos Cordon52d8a152014-06-17 19:08:45 -070025import android.content.ComponentName;
Santos Cordon5c6fa952014-07-20 17:47:12 -070026import android.content.Intent;
Ihab Awad542e0ea2014-05-16 10:22:16 -070027import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070028import android.os.Bundle;
Santos Cordon52d8a152014-06-17 19:08:45 -070029import android.os.Handler;
30import android.os.IBinder;
31import android.os.Looper;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070032import android.os.Message;
Hall Liub64ac4c2017-02-06 10:49:48 -080033import android.os.ParcelFileDescriptor;
34import android.os.RemoteException;
Brad Ebingerb32d4f82016-10-24 16:40:49 -070035import android.telecom.Logging.Session;
Andrew Lee14185762014-07-25 09:41:56 -070036
Brad Ebinger99f17ce2019-09-11 18:06:51 -070037import com.android.internal.annotations.VisibleForTesting;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070038import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070039import com.android.internal.telecom.IConnectionService;
40import com.android.internal.telecom.IConnectionServiceAdapter;
41import com.android.internal.telecom.RemoteServiceCallback;
Santos Cordon52d8a152014-06-17 19:08:45 -070042
Ihab Awad5d0410f2014-07-30 10:07:40 -070043import java.util.ArrayList;
Santos Cordonb6939982014-06-04 20:20:58 -070044import java.util.Collection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070045import java.util.Collections;
Santos Cordon52d8a152014-06-17 19:08:45 -070046import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070047import java.util.Map;
Santos Cordon823fd3c2014-08-07 18:35:18 -070048import java.util.UUID;
mike dooley95e80702014-09-18 14:07:52 -070049import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070050
51/**
Tyler Gunnf5035432017-01-09 09:43:12 -080052 * An abstract service that should be implemented by any apps which either:
53 * <ol>
54 * <li>Can make phone calls (VoIP or otherwise) and want those calls to be integrated into the
55 * built-in phone app. Referred to as a <b>system managed</b> {@link ConnectionService}.</li>
56 * <li>Are a standalone calling app and don't want their calls to be integrated into the
57 * built-in phone app. Referred to as a <b>self managed</b> {@link ConnectionService}.</li>
58 * </ol>
59 * Once implemented, the {@link ConnectionService} needs to take the following steps so that Telecom
60 * will bind to it:
Santos Cordona663f862014-10-29 13:49:58 -070061 * <p>
62 * 1. <i>Registration in AndroidManifest.xml</i>
63 * <br/>
64 * <pre>
65 * &lt;service android:name="com.example.package.MyConnectionService"
66 * android:label="@string/some_label_for_my_connection_service"
Yorke Lee249c12e2015-05-13 15:59:29 -070067 * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"&gt;
Santos Cordona663f862014-10-29 13:49:58 -070068 * &lt;intent-filter&gt;
69 * &lt;action android:name="android.telecom.ConnectionService" /&gt;
70 * &lt;/intent-filter&gt;
71 * &lt;/service&gt;
72 * </pre>
73 * <p>
74 * 2. <i> Registration of {@link PhoneAccount} with {@link TelecomManager}.</i>
75 * <br/>
76 * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
77 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080078 * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
kopriva82c591b2018-10-08 15:57:00 -070079 * before Telecom will bind to them. Self-managed {@link ConnectionService}s must be granted the
Tyler Gunnf5035432017-01-09 09:43:12 -080080 * appropriate permission before Telecom will bind to them.
81 * <p>
82 * Once registered and enabled by the user in the phone app settings or granted permission, telecom
83 * will bind to a {@link ConnectionService} implementation when it wants that
84 * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
85 * call through {@link TelecomManager#addNewIncomingCall}. The {@link ConnectionService} can then
86 * expect a call to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection}
87 * wherein it should provide a new instance of a {@link Connection} object. It is through this
88 * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
Santos Cordona663f862014-10-29 13:49:58 -070089 * receives call-commands such as answer, reject, hold and disconnect.
90 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080091 * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
Ihab Awad542e0ea2014-05-16 10:22:16 -070092 */
Sailesh Nepal2a46b902014-07-04 17:21:07 -070093public abstract class ConnectionService extends Service {
Santos Cordon5c6fa952014-07-20 17:47:12 -070094 /**
95 * The {@link Intent} that must be declared as handled by the service.
96 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070097 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
Tyler Gunnef9f6f92014-09-12 22:16:17 -070098 public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
Santos Cordon5c6fa952014-07-20 17:47:12 -070099
Tyler Gunn8bf76572017-04-06 15:30:08 -0700100 /**
101 * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
102 * being asked to create a new outgoing {@link Connection} is to perform a handover of an
103 * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}. Will
104 * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
105 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
106 * <p>
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700107 * When your {@link ConnectionService} receives this extra, it should communicate the fact that
108 * this is a handover to the other device's matching {@link ConnectionService}. That
Tyler Gunn8bf76572017-04-06 15:30:08 -0700109 * {@link ConnectionService} will continue the handover using
110 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700111 * {@link TelecomManager#EXTRA_IS_HANDOVER}. Telecom will match the phone numbers of the
112 * handover call on the other device with ongoing calls for {@link ConnectionService}s which
113 * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700114 * @hide
115 */
116 public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
117
Ihab Awad542e0ea2014-05-16 10:22:16 -0700118 // Flag controlling whether PII is emitted into the logs
Ihab Awad60ac30b2014-05-20 22:32:12 -0700119 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700120
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700121 // Session Definitions
122 private static final String SESSION_HANDLER = "H.";
123 private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
124 private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
125 private static final String SESSION_CREATE_CONN = "CS.crCo";
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700126 private static final String SESSION_CREATE_CONN_COMPLETE = "CS.crCoC";
Tyler Gunn44e01912017-01-31 10:49:05 -0800127 private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700128 private static final String SESSION_ABORT = "CS.ab";
129 private static final String SESSION_ANSWER = "CS.an";
130 private static final String SESSION_ANSWER_VIDEO = "CS.anV";
Pooja Jaind34698d2017-12-28 14:15:31 +0530131 private static final String SESSION_DEFLECT = "CS.def";
Ravi Palurif4b38e72020-02-05 12:35:41 +0530132 private static final String SESSION_TRANSFER = "CS.trans";
133 private static final String SESSION_CONSULTATIVE_TRANSFER = "CS.cTrans";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700134 private static final String SESSION_REJECT = "CS.r";
135 private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
136 private static final String SESSION_SILENCE = "CS.s";
137 private static final String SESSION_DISCONNECT = "CS.d";
138 private static final String SESSION_HOLD = "CS.h";
139 private static final String SESSION_UNHOLD = "CS.u";
140 private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
Grace Jia4e8dc102021-01-19 14:58:01 -0800141 private static final String SESSION_USING_ALTERNATIVE_UI = "CS.uAU";
142 private static final String SESSION_TRACKED_BY_NON_UI_SERVICE = "CS.tBNUS";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700143 private static final String SESSION_PLAY_DTMF = "CS.pDT";
144 private static final String SESSION_STOP_DTMF = "CS.sDT";
145 private static final String SESSION_CONFERENCE = "CS.c";
146 private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
147 private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
148 private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
Ravi Paluri404babb2020-01-23 19:02:44 +0530149 private static final String SESSION_ADD_PARTICIPANT = "CS.aP";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700150 private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
151 private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
152 private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800153 private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700154 private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
Hall Liub64ac4c2017-02-06 10:49:48 -0800155 private static final String SESSION_START_RTT = "CS.+RTT";
Hall Liua549fed2018-02-09 16:40:03 -0800156 private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
Hall Liub64ac4c2017-02-06 10:49:48 -0800157 private static final String SESSION_STOP_RTT = "CS.-RTT";
158 private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
Pengquan Meng731c1a32017-11-21 18:01:13 -0800159 private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
160 private static final String SESSION_CONNECTION_SERVICE_FOCUS_GAINED = "CS.cSFG";
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800161 private static final String SESSION_HANDOVER_FAILED = "CS.haF";
Ravi Paluri80aa2142019-12-02 11:57:37 +0530162 private static final String SESSION_CREATE_CONF = "CS.crConf";
163 private static final String SESSION_CREATE_CONF_COMPLETE = "CS.crConfC";
164 private static final String SESSION_CREATE_CONF_FAILED = "CS.crConfF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700165
Ihab Awad8aecfed2014-08-08 17:06:11 -0700166 private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700167 private static final int MSG_CREATE_CONNECTION = 2;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700168 private static final int MSG_ABORT = 3;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700169 private static final int MSG_ANSWER = 4;
170 private static final int MSG_REJECT = 5;
171 private static final int MSG_DISCONNECT = 6;
172 private static final int MSG_HOLD = 7;
173 private static final int MSG_UNHOLD = 8;
Yorke Lee4af59352015-05-13 14:14:54 -0700174 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700175 private static final int MSG_PLAY_DTMF_TONE = 10;
176 private static final int MSG_STOP_DTMF_TONE = 11;
177 private static final int MSG_CONFERENCE = 12;
178 private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700179 private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700180 private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
Tyler Gunnbe74de02014-08-29 14:51:48 -0700181 private static final int MSG_ANSWER_VIDEO = 17;
Santos Cordona4868042014-09-04 17:39:22 -0700182 private static final int MSG_MERGE_CONFERENCE = 18;
183 private static final int MSG_SWAP_CONFERENCE = 19;
Bryce Lee81901682015-08-28 16:38:02 -0700184 private static final int MSG_REJECT_WITH_MESSAGE = 20;
Bryce Leecac50772015-11-17 15:13:29 -0800185 private static final int MSG_SILENCE = 21;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700186 private static final int MSG_PULL_EXTERNAL_CALL = 22;
187 private static final int MSG_SEND_CALL_EVENT = 23;
Tyler Gunndee56a82016-03-23 16:06:34 -0700188 private static final int MSG_ON_EXTRAS_CHANGED = 24;
Tyler Gunn44e01912017-01-31 10:49:05 -0800189 private static final int MSG_CREATE_CONNECTION_FAILED = 25;
Hall Liub64ac4c2017-02-06 10:49:48 -0800190 private static final int MSG_ON_START_RTT = 26;
191 private static final int MSG_ON_STOP_RTT = 27;
192 private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700193 private static final int MSG_CREATE_CONNECTION_COMPLETE = 29;
Pengquan Meng731c1a32017-11-21 18:01:13 -0800194 private static final int MSG_CONNECTION_SERVICE_FOCUS_LOST = 30;
195 private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800196 private static final int MSG_HANDOVER_FAILED = 32;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800197 private static final int MSG_HANDOVER_COMPLETE = 33;
Pooja Jaind34698d2017-12-28 14:15:31 +0530198 private static final int MSG_DEFLECT = 34;
Ravi Paluri80aa2142019-12-02 11:57:37 +0530199 private static final int MSG_CREATE_CONFERENCE = 35;
200 private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
201 private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800202 private static final int MSG_REJECT_WITH_REASON = 38;
Ravi Paluri404babb2020-01-23 19:02:44 +0530203 private static final int MSG_ADD_PARTICIPANT = 39;
Ravi Palurif4b38e72020-02-05 12:35:41 +0530204 private static final int MSG_EXPLICIT_CALL_TRANSFER = 40;
205 private static final int MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE = 41;
Grace Jia4e8dc102021-01-19 14:58:01 -0800206 private static final int MSG_ON_CALL_FILTERING_COMPLETED = 42;
207 private static final int MSG_ON_USING_ALTERNATIVE_UI = 43;
208 private static final int MSG_ON_TRACKED_BY_NON_UI_SERVICE = 44;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700209
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700210 private static Connection sNullConnection;
211
mike dooley95e80702014-09-18 14:07:52 -0700212 private final Map<String, Connection> mConnectionById = new ConcurrentHashMap<>();
213 private final Map<Connection, String> mIdByConnection = new ConcurrentHashMap<>();
214 private final Map<String, Conference> mConferenceById = new ConcurrentHashMap<>();
215 private final Map<Conference, String> mIdByConference = new ConcurrentHashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700216 private final RemoteConnectionManager mRemoteConnectionManager =
217 new RemoteConnectionManager(this);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700218 private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700219 private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
Ihab Awad542e0ea2014-05-16 10:22:16 -0700220
Santos Cordon823fd3c2014-08-07 18:35:18 -0700221 private boolean mAreAccountsInitialized = false;
Santos Cordon0159ac02014-08-21 14:28:11 -0700222 private Conference sNullConference;
Tyler Gunnf0500bd2015-09-01 10:59:48 -0700223 private Object mIdSyncRoot = new Object();
224 private int mId = 0;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700225
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700226 private final IBinder mBinder = new IConnectionService.Stub() {
227 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700228 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
229 Session.Info sessionInfo) {
230 Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
231 try {
232 SomeArgs args = SomeArgs.obtain();
233 args.arg1 = adapter;
234 args.arg2 = Log.createSubsession();
235 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
236 } finally {
237 Log.endSession();
238 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700239 }
240
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700241 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
242 Session.Info sessionInfo) {
243 Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
244 try {
245 SomeArgs args = SomeArgs.obtain();
246 args.arg1 = adapter;
247 args.arg2 = Log.createSubsession();
248 mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
249 } finally {
250 Log.endSession();
251 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700252 }
253
254 @Override
Ihab Awadf8b69882014-07-25 15:14:01 -0700255 public void createConnection(
256 PhoneAccountHandle connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700257 String id,
Ihab Awadf8b69882014-07-25 15:14:01 -0700258 ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700259 boolean isIncoming,
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700260 boolean isUnknown,
261 Session.Info sessionInfo) {
262 Log.startSession(sessionInfo, SESSION_CREATE_CONN);
263 try {
264 SomeArgs args = SomeArgs.obtain();
265 args.arg1 = connectionManagerPhoneAccount;
266 args.arg2 = id;
267 args.arg3 = request;
268 args.arg4 = Log.createSubsession();
269 args.argi1 = isIncoming ? 1 : 0;
270 args.argi2 = isUnknown ? 1 : 0;
271 mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
272 } finally {
273 Log.endSession();
274 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700275 }
276
277 @Override
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700278 public void createConnectionComplete(String id, Session.Info sessionInfo) {
279 Log.startSession(sessionInfo, SESSION_CREATE_CONN_COMPLETE);
280 try {
281 SomeArgs args = SomeArgs.obtain();
282 args.arg1 = id;
283 args.arg2 = Log.createSubsession();
284 mHandler.obtainMessage(MSG_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
285 } finally {
286 Log.endSession();
287 }
288 }
289
290 @Override
Tyler Gunn44e01912017-01-31 10:49:05 -0800291 public void createConnectionFailed(
Tyler Gunn159f35c2017-03-02 09:28:37 -0800292 PhoneAccountHandle connectionManagerPhoneAccount,
Tyler Gunn44e01912017-01-31 10:49:05 -0800293 String callId,
294 ConnectionRequest request,
295 boolean isIncoming,
296 Session.Info sessionInfo) {
297 Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
298 try {
299 SomeArgs args = SomeArgs.obtain();
300 args.arg1 = callId;
301 args.arg2 = request;
302 args.arg3 = Log.createSubsession();
Tyler Gunn159f35c2017-03-02 09:28:37 -0800303 args.arg4 = connectionManagerPhoneAccount;
Tyler Gunn44e01912017-01-31 10:49:05 -0800304 args.argi1 = isIncoming ? 1 : 0;
305 mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
306 } finally {
307 Log.endSession();
308 }
309 }
310
311 @Override
Ravi Paluri80aa2142019-12-02 11:57:37 +0530312 public void createConference(
313 PhoneAccountHandle connectionManagerPhoneAccount,
314 String id,
315 ConnectionRequest request,
316 boolean isIncoming,
317 boolean isUnknown,
318 Session.Info sessionInfo) {
319 Log.startSession(sessionInfo, SESSION_CREATE_CONF);
320 try {
321 SomeArgs args = SomeArgs.obtain();
322 args.arg1 = connectionManagerPhoneAccount;
323 args.arg2 = id;
324 args.arg3 = request;
325 args.arg4 = Log.createSubsession();
326 args.argi1 = isIncoming ? 1 : 0;
327 args.argi2 = isUnknown ? 1 : 0;
328 mHandler.obtainMessage(MSG_CREATE_CONFERENCE, args).sendToTarget();
329 } finally {
330 Log.endSession();
331 }
332 }
333
334 @Override
335 public void createConferenceComplete(String id, Session.Info sessionInfo) {
336 Log.startSession(sessionInfo, SESSION_CREATE_CONF_COMPLETE);
337 try {
338 SomeArgs args = SomeArgs.obtain();
339 args.arg1 = id;
340 args.arg2 = Log.createSubsession();
341 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_COMPLETE, args).sendToTarget();
342 } finally {
343 Log.endSession();
344 }
345 }
346
347 @Override
348 public void createConferenceFailed(
349 PhoneAccountHandle connectionManagerPhoneAccount,
350 String callId,
351 ConnectionRequest request,
352 boolean isIncoming,
353 Session.Info sessionInfo) {
354 Log.startSession(sessionInfo, SESSION_CREATE_CONF_FAILED);
355 try {
356 SomeArgs args = SomeArgs.obtain();
357 args.arg1 = callId;
358 args.arg2 = request;
359 args.arg3 = Log.createSubsession();
360 args.arg4 = connectionManagerPhoneAccount;
361 args.argi1 = isIncoming ? 1 : 0;
362 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_FAILED, args).sendToTarget();
363 } finally {
364 Log.endSession();
365 }
366 }
367
368 @Override
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800369 public void handoverFailed(String callId, ConnectionRequest request, int reason,
370 Session.Info sessionInfo) {
371 Log.startSession(sessionInfo, SESSION_HANDOVER_FAILED);
372 try {
373 SomeArgs args = SomeArgs.obtain();
374 args.arg1 = callId;
375 args.arg2 = request;
376 args.arg3 = Log.createSubsession();
377 args.arg4 = reason;
378 mHandler.obtainMessage(MSG_HANDOVER_FAILED, args).sendToTarget();
379 } finally {
380 Log.endSession();
381 }
382 }
383
384 @Override
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800385 public void handoverComplete(String callId, Session.Info sessionInfo) {
386 Log.startSession(sessionInfo, SESSION_HANDOVER_COMPLETE);
387 try {
388 SomeArgs args = SomeArgs.obtain();
389 args.arg1 = callId;
390 args.arg2 = Log.createSubsession();
391 mHandler.obtainMessage(MSG_HANDOVER_COMPLETE, args).sendToTarget();
392 } finally {
393 Log.endSession();
394 }
395 }
396
397 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700398 public void abort(String callId, Session.Info sessionInfo) {
399 Log.startSession(sessionInfo, SESSION_ABORT);
400 try {
401 SomeArgs args = SomeArgs.obtain();
402 args.arg1 = callId;
403 args.arg2 = Log.createSubsession();
404 mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
405 } finally {
406 Log.endSession();
407 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700408 }
409
410 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700411 public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
412 Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
413 try {
414 SomeArgs args = SomeArgs.obtain();
415 args.arg1 = callId;
416 args.arg2 = Log.createSubsession();
417 args.argi1 = videoState;
418 mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
419 } finally {
420 Log.endSession();
421 }
Tyler Gunnbe74de02014-08-29 14:51:48 -0700422 }
423
424 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700425 public void answer(String callId, Session.Info sessionInfo) {
426 Log.startSession(sessionInfo, SESSION_ANSWER);
427 try {
428 SomeArgs args = SomeArgs.obtain();
429 args.arg1 = callId;
430 args.arg2 = Log.createSubsession();
431 mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
432 } finally {
433 Log.endSession();
434 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700435 }
436
437 @Override
Pooja Jaind34698d2017-12-28 14:15:31 +0530438 public void deflect(String callId, Uri address, Session.Info sessionInfo) {
439 Log.startSession(sessionInfo, SESSION_DEFLECT);
440 try {
441 SomeArgs args = SomeArgs.obtain();
442 args.arg1 = callId;
443 args.arg2 = address;
444 args.arg3 = Log.createSubsession();
445 mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
446 } finally {
447 Log.endSession();
448 }
449 }
450
451 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700452 public void reject(String callId, Session.Info sessionInfo) {
453 Log.startSession(sessionInfo, SESSION_REJECT);
454 try {
455 SomeArgs args = SomeArgs.obtain();
456 args.arg1 = callId;
457 args.arg2 = Log.createSubsession();
458 mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
459 } finally {
460 Log.endSession();
461 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700462 }
463
464 @Override
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800465 public void rejectWithReason(String callId,
466 @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
467 Log.startSession(sessionInfo, SESSION_REJECT);
468 try {
469 SomeArgs args = SomeArgs.obtain();
470 args.arg1 = callId;
471 args.argi1 = rejectReason;
472 args.arg2 = Log.createSubsession();
473 mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
474 } finally {
475 Log.endSession();
476 }
477 }
478
479 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700480 public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
481 Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
482 try {
483 SomeArgs args = SomeArgs.obtain();
484 args.arg1 = callId;
485 args.arg2 = message;
486 args.arg3 = Log.createSubsession();
487 mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
488 } finally {
489 Log.endSession();
490 }
Bryce Lee81901682015-08-28 16:38:02 -0700491 }
492
493 @Override
Ravi Palurif4b38e72020-02-05 12:35:41 +0530494 public void transfer(@NonNull String callId, @NonNull Uri number,
495 boolean isConfirmationRequired, Session.Info sessionInfo) {
496 Log.startSession(sessionInfo, SESSION_TRANSFER);
497 try {
498 SomeArgs args = SomeArgs.obtain();
499 args.arg1 = callId;
500 args.arg2 = number;
501 args.argi1 = isConfirmationRequired ? 1 : 0;
502 args.arg3 = Log.createSubsession();
503 mHandler.obtainMessage(MSG_EXPLICIT_CALL_TRANSFER, args).sendToTarget();
504 } finally {
505 Log.endSession();
506 }
507 }
508
509 @Override
510 public void consultativeTransfer(@NonNull String callId, @NonNull String otherCallId,
511 Session.Info sessionInfo) {
512 Log.startSession(sessionInfo, SESSION_CONSULTATIVE_TRANSFER);
513 try {
514 SomeArgs args = SomeArgs.obtain();
515 args.arg1 = callId;
516 args.arg2 = otherCallId;
517 args.arg3 = Log.createSubsession();
518 mHandler.obtainMessage(
519 MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE, args).sendToTarget();
520 } finally {
521 Log.endSession();
522 }
523 }
524
525 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700526 public void silence(String callId, Session.Info sessionInfo) {
527 Log.startSession(sessionInfo, SESSION_SILENCE);
528 try {
529 SomeArgs args = SomeArgs.obtain();
530 args.arg1 = callId;
531 args.arg2 = Log.createSubsession();
532 mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
533 } finally {
534 Log.endSession();
535 }
Bryce Leecac50772015-11-17 15:13:29 -0800536 }
537
538 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700539 public void disconnect(String callId, Session.Info sessionInfo) {
540 Log.startSession(sessionInfo, SESSION_DISCONNECT);
541 try {
542 SomeArgs args = SomeArgs.obtain();
543 args.arg1 = callId;
544 args.arg2 = Log.createSubsession();
545 mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
546 } finally {
547 Log.endSession();
548 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700549 }
550
551 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700552 public void hold(String callId, Session.Info sessionInfo) {
553 Log.startSession(sessionInfo, SESSION_HOLD);
554 try {
555 SomeArgs args = SomeArgs.obtain();
556 args.arg1 = callId;
557 args.arg2 = Log.createSubsession();
558 mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
559 } finally {
560 Log.endSession();
561 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700562 }
563
564 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700565 public void unhold(String callId, Session.Info sessionInfo) {
566 Log.startSession(sessionInfo, SESSION_UNHOLD);
567 try {
568 SomeArgs args = SomeArgs.obtain();
569 args.arg1 = callId;
570 args.arg2 = Log.createSubsession();
571 mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
572 } finally {
573 Log.endSession();
574 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700575 }
576
577 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700578 public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
579 Session.Info sessionInfo) {
580 Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
581 try {
582 SomeArgs args = SomeArgs.obtain();
583 args.arg1 = callId;
584 args.arg2 = callAudioState;
585 args.arg3 = Log.createSubsession();
586 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
587 } finally {
588 Log.endSession();
589 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700590 }
591
592 @Override
Grace Jia4e8dc102021-01-19 14:58:01 -0800593 public void onUsingAlternativeUi(String callId, boolean usingAlternativeUiShowing,
594 Session.Info sessionInfo) {
595 Log.startSession(sessionInfo, SESSION_USING_ALTERNATIVE_UI);
596 try {
597 SomeArgs args = SomeArgs.obtain();
598 args.arg1 = callId;
599 args.arg2 = usingAlternativeUiShowing;
600 args.arg3 = Log.createSubsession();
601 mHandler.obtainMessage(MSG_ON_USING_ALTERNATIVE_UI, args).sendToTarget();
602 } finally {
603 Log.endSession();
604 }
605 }
606
607 @Override
608 public void onTrackedByNonUiService(String callId, boolean isTracked,
609 Session.Info sessionInfo) {
610 Log.startSession(sessionInfo, SESSION_TRACKED_BY_NON_UI_SERVICE);
611 try {
612 SomeArgs args = SomeArgs.obtain();
613 args.arg1 = callId;
614 args.arg2 = isTracked;
615 args.arg3 = Log.createSubsession();
616 mHandler.obtainMessage(MSG_ON_TRACKED_BY_NON_UI_SERVICE, args).sendToTarget();
617 } finally {
618 Log.endSession();
619 }
620 }
621
622 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700623 public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
624 Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
625 try {
626 SomeArgs args = SomeArgs.obtain();
627 args.arg1 = digit;
628 args.arg2 = callId;
629 args.arg3 = Log.createSubsession();
630 mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, args).sendToTarget();
631 } finally {
632 Log.endSession();
633 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700634 }
635
636 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700637 public void stopDtmfTone(String callId, Session.Info sessionInfo) {
638 Log.startSession(sessionInfo, SESSION_STOP_DTMF);
639 try {
640 SomeArgs args = SomeArgs.obtain();
641 args.arg1 = callId;
642 args.arg2 = Log.createSubsession();
643 mHandler.obtainMessage(MSG_STOP_DTMF_TONE, args).sendToTarget();
644 } finally {
645 Log.endSession();
646 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700647 }
648
649 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700650 public void conference(String callId1, String callId2, Session.Info sessionInfo) {
651 Log.startSession(sessionInfo, SESSION_CONFERENCE);
652 try {
653 SomeArgs args = SomeArgs.obtain();
654 args.arg1 = callId1;
655 args.arg2 = callId2;
656 args.arg3 = Log.createSubsession();
657 mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
658 } finally {
659 Log.endSession();
660 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700661 }
662
663 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700664 public void splitFromConference(String callId, Session.Info sessionInfo) {
665 Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
666 try {
667 SomeArgs args = SomeArgs.obtain();
668 args.arg1 = callId;
669 args.arg2 = Log.createSubsession();
670 mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
671 } finally {
672 Log.endSession();
673 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700674 }
675
676 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700677 public void mergeConference(String callId, Session.Info sessionInfo) {
678 Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
679 try {
680 SomeArgs args = SomeArgs.obtain();
681 args.arg1 = callId;
682 args.arg2 = Log.createSubsession();
683 mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
684 } finally {
685 Log.endSession();
686 }
Santos Cordona4868042014-09-04 17:39:22 -0700687 }
688
689 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700690 public void swapConference(String callId, Session.Info sessionInfo) {
691 Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
692 try {
693 SomeArgs args = SomeArgs.obtain();
694 args.arg1 = callId;
695 args.arg2 = Log.createSubsession();
696 mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
697 } finally {
698 Log.endSession();
699 }
Santos Cordona4868042014-09-04 17:39:22 -0700700 }
701
702 @Override
Ravi Paluri404babb2020-01-23 19:02:44 +0530703 public void addConferenceParticipants(String callId, List<Uri> participants,
704 Session.Info sessionInfo) {
705 Log.startSession(sessionInfo, SESSION_ADD_PARTICIPANT);
706 try {
707 SomeArgs args = SomeArgs.obtain();
708 args.arg1 = callId;
709 args.arg2 = participants;
710 args.arg3 = Log.createSubsession();
711 mHandler.obtainMessage(MSG_ADD_PARTICIPANT, args).sendToTarget();
712 } finally {
713 Log.endSession();
714 }
715 }
716
717 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700718 public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
719 Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
720 try {
721 SomeArgs args = SomeArgs.obtain();
722 args.arg1 = callId;
723 args.arg2 = Log.createSubsession();
724 args.argi1 = proceed ? 1 : 0;
725 mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
726 } finally {
727 Log.endSession();
728 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700729 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700730
731 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700732 public void pullExternalCall(String callId, Session.Info sessionInfo) {
733 Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
734 try {
735 SomeArgs args = SomeArgs.obtain();
736 args.arg1 = callId;
737 args.arg2 = Log.createSubsession();
738 mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
739 } finally {
740 Log.endSession();
741 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700742 }
743
744 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700745 public void sendCallEvent(String callId, String event, Bundle extras,
746 Session.Info sessionInfo) {
747 Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
748 try {
749 SomeArgs args = SomeArgs.obtain();
750 args.arg1 = callId;
751 args.arg2 = event;
752 args.arg3 = extras;
753 args.arg4 = Log.createSubsession();
754 mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
755 } finally {
756 Log.endSession();
757 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700758 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700759
760 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700761 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
762 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
763 try {
764 SomeArgs args = SomeArgs.obtain();
765 args.arg1 = callId;
766 args.arg2 = extras;
767 args.arg3 = Log.createSubsession();
768 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
769 } finally {
770 Log.endSession();
771 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700772 }
Hall Liub64ac4c2017-02-06 10:49:48 -0800773
774 @Override
775 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
776 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
777 Log.startSession(sessionInfo, SESSION_START_RTT);
778 try {
779 SomeArgs args = SomeArgs.obtain();
780 args.arg1 = callId;
781 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
782 args.arg3 = Log.createSubsession();
783 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
784 } finally {
785 Log.endSession();
786 }
787 }
788
789 @Override
790 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
791 Log.startSession(sessionInfo, SESSION_STOP_RTT);
792 try {
793 SomeArgs args = SomeArgs.obtain();
794 args.arg1 = callId;
795 args.arg2 = Log.createSubsession();
796 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
797 } finally {
798 Log.endSession();
799 }
800 }
801
802 @Override
803 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
804 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
805 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
806 try {
807 SomeArgs args = SomeArgs.obtain();
808 args.arg1 = callId;
809 if (toInCall == null || fromInCall == null) {
810 args.arg2 = null;
811 } else {
812 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
813 }
814 args.arg3 = Log.createSubsession();
815 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
816 } finally {
817 Log.endSession();
818 }
819 }
Pengquan Meng731c1a32017-11-21 18:01:13 -0800820
821 @Override
822 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
823 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
824 try {
825 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
826 } finally {
827 Log.endSession();
828 }
829 }
830
831 @Override
832 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
833 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
834 try {
835 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
836 } finally {
837 Log.endSession();
838 }
839 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700840 };
841
842 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
843 @Override
844 public void handleMessage(Message msg) {
845 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700846 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
847 SomeArgs args = (SomeArgs) msg.obj;
848 try {
849 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
850 Log.continueSession((Session) args.arg2,
851 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
852 mAdapter.addAdapter(adapter);
853 onAdapterAttached();
854 } finally {
855 args.recycle();
856 Log.endSession();
857 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700858 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700859 }
860 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
861 SomeArgs args = (SomeArgs) msg.obj;
862 try {
863 Log.continueSession((Session) args.arg2,
864 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
865 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
866 } finally {
867 args.recycle();
868 Log.endSession();
869 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700870 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700871 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700872 case MSG_CREATE_CONNECTION: {
873 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700874 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -0700875 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700876 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -0700877 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700878 final String id = (String) args.arg2;
879 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700880 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -0700881 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700882 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700883 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700884 mPreInitializationConnectionRequests.add(
885 new android.telecom.Logging.Runnable(
886 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
887 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700888 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700889 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700890 createConnection(
891 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700892 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700893 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700894 isIncoming,
895 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700896 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700897 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -0700898 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700899 createConnection(
900 connectionManagerPhoneAccount,
901 id,
902 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700903 isIncoming,
904 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700905 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700906 } finally {
907 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700908 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -0700909 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700910 break;
Ihab Awadf8b69882014-07-25 15:14:01 -0700911 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700912 case MSG_CREATE_CONNECTION_COMPLETE: {
913 SomeArgs args = (SomeArgs) msg.obj;
914 Log.continueSession((Session) args.arg2,
915 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
916 try {
917 final String id = (String) args.arg1;
918 if (!mAreAccountsInitialized) {
919 Log.d(this, "Enqueueing pre-init request %s", id);
920 mPreInitializationConnectionRequests.add(
921 new android.telecom.Logging.Runnable(
922 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
923 + ".pICR",
924 null /*lock*/) {
925 @Override
926 public void loggedRun() {
927 notifyCreateConnectionComplete(id);
928 }
929 }.prepare());
930 } else {
931 notifyCreateConnectionComplete(id);
932 }
933 } finally {
934 args.recycle();
935 Log.endSession();
936 }
937 break;
938 }
Tyler Gunn44e01912017-01-31 10:49:05 -0800939 case MSG_CREATE_CONNECTION_FAILED: {
940 SomeArgs args = (SomeArgs) msg.obj;
941 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
942 SESSION_CREATE_CONN_FAILED);
943 try {
944 final String id = (String) args.arg1;
945 final ConnectionRequest request = (ConnectionRequest) args.arg2;
946 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800947 final PhoneAccountHandle connectionMgrPhoneAccount =
948 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -0800949 if (!mAreAccountsInitialized) {
950 Log.d(this, "Enqueueing pre-init request %s", id);
951 mPreInitializationConnectionRequests.add(
952 new android.telecom.Logging.Runnable(
953 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
954 null /*lock*/) {
955 @Override
956 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800957 createConnectionFailed(connectionMgrPhoneAccount, id,
958 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800959 }
960 }.prepare());
961 } else {
962 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -0800963 createConnectionFailed(connectionMgrPhoneAccount, id, request,
964 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800965 }
966 } finally {
967 args.recycle();
968 Log.endSession();
969 }
970 break;
971 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530972 case MSG_CREATE_CONFERENCE: {
973 SomeArgs args = (SomeArgs) msg.obj;
974 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
975 try {
976 final PhoneAccountHandle connectionManagerPhoneAccount =
977 (PhoneAccountHandle) args.arg1;
978 final String id = (String) args.arg2;
979 final ConnectionRequest request = (ConnectionRequest) args.arg3;
980 final boolean isIncoming = args.argi1 == 1;
981 final boolean isUnknown = args.argi2 == 1;
982 if (!mAreAccountsInitialized) {
983 Log.d(this, "Enqueueing pre-initconference request %s", id);
984 mPreInitializationConnectionRequests.add(
985 new android.telecom.Logging.Runnable(
986 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
987 null /*lock*/) {
988 @Override
989 public void loggedRun() {
990 createConference(connectionManagerPhoneAccount,
991 id,
992 request,
993 isIncoming,
994 isUnknown);
995 }
996 }.prepare());
997 } else {
998 createConference(connectionManagerPhoneAccount,
999 id,
1000 request,
1001 isIncoming,
1002 isUnknown);
1003 }
1004 } finally {
1005 args.recycle();
1006 Log.endSession();
1007 }
1008 break;
1009 }
1010 case MSG_CREATE_CONFERENCE_COMPLETE: {
1011 SomeArgs args = (SomeArgs) msg.obj;
1012 Log.continueSession((Session) args.arg2,
1013 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1014 try {
1015 final String id = (String) args.arg1;
1016 if (!mAreAccountsInitialized) {
1017 Log.d(this, "Enqueueing pre-init conference request %s", id);
1018 mPreInitializationConnectionRequests.add(
1019 new android.telecom.Logging.Runnable(
1020 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
1021 + ".pIConfR",
1022 null /*lock*/) {
1023 @Override
1024 public void loggedRun() {
1025 notifyCreateConferenceComplete(id);
1026 }
1027 }.prepare());
1028 } else {
1029 notifyCreateConferenceComplete(id);
1030 }
1031 } finally {
1032 args.recycle();
1033 Log.endSession();
1034 }
1035 break;
1036 }
1037 case MSG_CREATE_CONFERENCE_FAILED: {
1038 SomeArgs args = (SomeArgs) msg.obj;
1039 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1040 SESSION_CREATE_CONN_FAILED);
1041 try {
1042 final String id = (String) args.arg1;
1043 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1044 final boolean isIncoming = args.argi1 == 1;
1045 final PhoneAccountHandle connectionMgrPhoneAccount =
1046 (PhoneAccountHandle) args.arg4;
1047 if (!mAreAccountsInitialized) {
1048 Log.d(this, "Enqueueing pre-init conference request %s", id);
1049 mPreInitializationConnectionRequests.add(
1050 new android.telecom.Logging.Runnable(
1051 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
1052 + ".pIConfR",
1053 null /*lock*/) {
1054 @Override
1055 public void loggedRun() {
1056 createConferenceFailed(connectionMgrPhoneAccount, id,
1057 request, isIncoming);
1058 }
1059 }.prepare());
1060 } else {
1061 Log.i(this, "createConferenceFailed %s", id);
1062 createConferenceFailed(connectionMgrPhoneAccount, id, request,
1063 isIncoming);
1064 }
1065 } finally {
1066 args.recycle();
1067 Log.endSession();
1068 }
1069 break;
1070 }
1071
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001072 case MSG_HANDOVER_FAILED: {
1073 SomeArgs args = (SomeArgs) msg.obj;
1074 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1075 SESSION_HANDOVER_FAILED);
1076 try {
1077 final String id = (String) args.arg1;
1078 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1079 final int reason = (int) args.arg4;
1080 if (!mAreAccountsInitialized) {
1081 Log.d(this, "Enqueueing pre-init request %s", id);
1082 mPreInitializationConnectionRequests.add(
1083 new android.telecom.Logging.Runnable(
1084 SESSION_HANDLER
1085 + SESSION_HANDOVER_FAILED + ".pICR",
1086 null /*lock*/) {
1087 @Override
1088 public void loggedRun() {
1089 handoverFailed(id, request, reason);
1090 }
1091 }.prepare());
1092 } else {
1093 Log.i(this, "createConnectionFailed %s", id);
1094 handoverFailed(id, request, reason);
1095 }
1096 } finally {
1097 args.recycle();
1098 Log.endSession();
1099 }
1100 break;
1101 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001102 case MSG_ABORT: {
1103 SomeArgs args = (SomeArgs) msg.obj;
1104 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1105 try {
1106 abort((String) args.arg1);
1107 } finally {
1108 args.recycle();
1109 Log.endSession();
1110 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001111 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001112 }
1113 case MSG_ANSWER: {
1114 SomeArgs args = (SomeArgs) msg.obj;
1115 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1116 try {
1117 answer((String) args.arg1);
1118 } finally {
1119 args.recycle();
1120 Log.endSession();
1121 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001122 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001123 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001124 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001125 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001126 Log.continueSession((Session) args.arg2,
1127 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001128 try {
1129 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001130 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001131 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001132 } finally {
1133 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001134 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001135 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001136 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001137 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301138 case MSG_DEFLECT: {
1139 SomeArgs args = (SomeArgs) msg.obj;
1140 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1141 try {
1142 deflect((String) args.arg1, (Uri) args.arg2);
1143 } finally {
1144 args.recycle();
1145 Log.endSession();
1146 }
1147 break;
1148 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001149 case MSG_REJECT: {
1150 SomeArgs args = (SomeArgs) msg.obj;
1151 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1152 try {
1153 reject((String) args.arg1);
1154 } finally {
1155 args.recycle();
1156 Log.endSession();
1157 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001158 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001159 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001160 case MSG_REJECT_WITH_REASON: {
1161 SomeArgs args = (SomeArgs) msg.obj;
1162 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1163 try {
1164 reject((String) args.arg1, args.argi1);
1165 } finally {
1166 args.recycle();
1167 Log.endSession();
1168 }
1169 break;
1170 }
Bryce Lee81901682015-08-28 16:38:02 -07001171 case MSG_REJECT_WITH_MESSAGE: {
1172 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001173 Log.continueSession((Session) args.arg3,
1174 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001175 try {
1176 reject((String) args.arg1, (String) args.arg2);
1177 } finally {
1178 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001179 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001180 }
1181 break;
1182 }
Ravi Palurif4b38e72020-02-05 12:35:41 +05301183 case MSG_EXPLICIT_CALL_TRANSFER: {
1184 SomeArgs args = (SomeArgs) msg.obj;
1185 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_TRANSFER);
1186 try {
1187 final boolean isConfirmationRequired = args.argi1 == 1;
1188 transfer((String) args.arg1, (Uri) args.arg2, isConfirmationRequired);
1189 } finally {
1190 args.recycle();
1191 Log.endSession();
1192 }
1193 break;
1194 }
1195 case MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE: {
1196 SomeArgs args = (SomeArgs) msg.obj;
1197 Log.continueSession(
1198 (Session) args.arg3, SESSION_HANDLER + SESSION_CONSULTATIVE_TRANSFER);
1199 try {
1200 consultativeTransfer((String) args.arg1, (String) args.arg2);
1201 } finally {
1202 args.recycle();
1203 Log.endSession();
1204 }
1205 break;
1206 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001207 case MSG_DISCONNECT: {
1208 SomeArgs args = (SomeArgs) msg.obj;
1209 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1210 try {
1211 disconnect((String) args.arg1);
1212 } finally {
1213 args.recycle();
1214 Log.endSession();
1215 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001216 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001217 }
1218 case MSG_SILENCE: {
1219 SomeArgs args = (SomeArgs) msg.obj;
1220 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1221 try {
1222 silence((String) args.arg1);
1223 } finally {
1224 args.recycle();
1225 Log.endSession();
1226 }
Bryce Leecac50772015-11-17 15:13:29 -08001227 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001228 }
1229 case MSG_HOLD: {
1230 SomeArgs args = (SomeArgs) msg.obj;
1231 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1232 try {
1233 hold((String) args.arg1);
1234 } finally {
1235 args.recycle();
1236 Log.endSession();
1237 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001238 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001239 }
1240 case MSG_UNHOLD: {
1241 SomeArgs args = (SomeArgs) msg.obj;
1242 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1243 try {
1244 unhold((String) args.arg1);
1245 } finally {
1246 args.recycle();
1247 Log.endSession();
1248 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001249 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001250 }
Yorke Lee4af59352015-05-13 14:14:54 -07001251 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001252 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001253 Log.continueSession((Session) args.arg3,
1254 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001255 try {
1256 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001257 CallAudioState audioState = (CallAudioState) args.arg2;
1258 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001259 } finally {
1260 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001261 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001262 }
1263 break;
1264 }
Grace Jia4e8dc102021-01-19 14:58:01 -08001265 case MSG_ON_USING_ALTERNATIVE_UI: {
1266 SomeArgs args = (SomeArgs) msg.obj;
1267 Log.continueSession((Session) args.arg3,
1268 SESSION_HANDLER + SESSION_USING_ALTERNATIVE_UI);
1269 try {
1270 String callId = (String) args.arg1;
1271 boolean isUsingAlternativeUi = (boolean) args.arg2;
1272 onUsingAlternativeUi(callId, isUsingAlternativeUi);
1273 } finally {
1274 args.recycle();
1275 Log.endSession();
1276 }
1277 break;
1278 }
1279 case MSG_ON_TRACKED_BY_NON_UI_SERVICE: {
1280 SomeArgs args = (SomeArgs) msg.obj;
1281 Log.continueSession((Session) args.arg3,
1282 SESSION_HANDLER + SESSION_TRACKED_BY_NON_UI_SERVICE);
1283 try {
1284 String callId = (String) args.arg1;
1285 boolean isTracked = (boolean) args.arg2;
1286 onTrackedByNonUiService(callId, isTracked);
1287 } finally {
1288 args.recycle();
1289 Log.endSession();
1290 }
1291 break;
1292 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001293 case MSG_PLAY_DTMF_TONE: {
1294 SomeArgs args = (SomeArgs) msg.obj;
1295 try {
1296 Log.continueSession((Session) args.arg3,
1297 SESSION_HANDLER + SESSION_PLAY_DTMF);
1298 playDtmfTone((String) args.arg2, (char) args.arg1);
1299 } finally {
1300 args.recycle();
1301 Log.endSession();
1302 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001303 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001304 }
1305 case MSG_STOP_DTMF_TONE: {
1306 SomeArgs args = (SomeArgs) msg.obj;
1307 try {
1308 Log.continueSession((Session) args.arg2,
1309 SESSION_HANDLER + SESSION_STOP_DTMF);
1310 stopDtmfTone((String) args.arg1);
1311 } finally {
1312 args.recycle();
1313 Log.endSession();
1314 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001315 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001316 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001317 case MSG_CONFERENCE: {
1318 SomeArgs args = (SomeArgs) msg.obj;
1319 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001320 Log.continueSession((Session) args.arg3,
1321 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001322 String callId1 = (String) args.arg1;
1323 String callId2 = (String) args.arg2;
1324 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001325 } finally {
1326 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001327 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001328 }
1329 break;
1330 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001331 case MSG_SPLIT_FROM_CONFERENCE: {
1332 SomeArgs args = (SomeArgs) msg.obj;
1333 try {
1334 Log.continueSession((Session) args.arg2,
1335 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1336 splitFromConference((String) args.arg1);
1337 } finally {
1338 args.recycle();
1339 Log.endSession();
1340 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001341 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001342 }
1343 case MSG_MERGE_CONFERENCE: {
1344 SomeArgs args = (SomeArgs) msg.obj;
1345 try {
1346 Log.continueSession((Session) args.arg2,
1347 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1348 mergeConference((String) args.arg1);
1349 } finally {
1350 args.recycle();
1351 Log.endSession();
1352 }
Santos Cordona4868042014-09-04 17:39:22 -07001353 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001354 }
1355 case MSG_SWAP_CONFERENCE: {
1356 SomeArgs args = (SomeArgs) msg.obj;
1357 try {
1358 Log.continueSession((Session) args.arg2,
1359 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1360 swapConference((String) args.arg1);
1361 } finally {
1362 args.recycle();
1363 Log.endSession();
1364 }
Santos Cordona4868042014-09-04 17:39:22 -07001365 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001366 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301367 case MSG_ADD_PARTICIPANT: {
1368 SomeArgs args = (SomeArgs) msg.obj;
1369 try {
1370 Log.continueSession((Session) args.arg3,
1371 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1372 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1373 } finally {
1374 args.recycle();
1375 Log.endSession();
1376 }
1377 break;
1378 }
1379
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001380 case MSG_ON_POST_DIAL_CONTINUE: {
1381 SomeArgs args = (SomeArgs) msg.obj;
1382 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001383 Log.continueSession((Session) args.arg2,
1384 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001385 String callId = (String) args.arg1;
1386 boolean proceed = (args.argi1 == 1);
1387 onPostDialContinue(callId, proceed);
1388 } finally {
1389 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001390 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001391 }
1392 break;
1393 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001394 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001395 SomeArgs args = (SomeArgs) msg.obj;
1396 try {
1397 Log.continueSession((Session) args.arg2,
1398 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1399 pullExternalCall((String) args.arg1);
1400 } finally {
1401 args.recycle();
1402 Log.endSession();
1403 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001404 break;
1405 }
1406 case MSG_SEND_CALL_EVENT: {
1407 SomeArgs args = (SomeArgs) msg.obj;
1408 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001409 Log.continueSession((Session) args.arg4,
1410 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001411 String callId = (String) args.arg1;
1412 String event = (String) args.arg2;
1413 Bundle extras = (Bundle) args.arg3;
1414 sendCallEvent(callId, event, extras);
1415 } finally {
1416 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001417 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001418 }
1419 break;
1420 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001421 case MSG_HANDOVER_COMPLETE: {
1422 SomeArgs args = (SomeArgs) msg.obj;
1423 try {
1424 Log.continueSession((Session) args.arg2,
1425 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1426 String callId = (String) args.arg1;
1427 notifyHandoverComplete(callId);
1428 } finally {
1429 args.recycle();
1430 Log.endSession();
1431 }
1432 break;
1433 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001434 case MSG_ON_EXTRAS_CHANGED: {
1435 SomeArgs args = (SomeArgs) msg.obj;
1436 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001437 Log.continueSession((Session) args.arg3,
1438 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001439 String callId = (String) args.arg1;
1440 Bundle extras = (Bundle) args.arg2;
1441 handleExtrasChanged(callId, extras);
1442 } finally {
1443 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001444 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001445 }
1446 break;
1447 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001448 case MSG_ON_START_RTT: {
1449 SomeArgs args = (SomeArgs) msg.obj;
1450 try {
1451 Log.continueSession((Session) args.arg3,
1452 SESSION_HANDLER + SESSION_START_RTT);
1453 String callId = (String) args.arg1;
1454 Connection.RttTextStream rttTextStream =
1455 (Connection.RttTextStream) args.arg2;
1456 startRtt(callId, rttTextStream);
1457 } finally {
1458 args.recycle();
1459 Log.endSession();
1460 }
1461 break;
1462 }
1463 case MSG_ON_STOP_RTT: {
1464 SomeArgs args = (SomeArgs) msg.obj;
1465 try {
1466 Log.continueSession((Session) args.arg2,
1467 SESSION_HANDLER + SESSION_STOP_RTT);
1468 String callId = (String) args.arg1;
1469 stopRtt(callId);
1470 } finally {
1471 args.recycle();
1472 Log.endSession();
1473 }
1474 break;
1475 }
1476 case MSG_RTT_UPGRADE_RESPONSE: {
1477 SomeArgs args = (SomeArgs) msg.obj;
1478 try {
1479 Log.continueSession((Session) args.arg3,
1480 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1481 String callId = (String) args.arg1;
1482 Connection.RttTextStream rttTextStream =
1483 (Connection.RttTextStream) args.arg2;
1484 handleRttUpgradeResponse(callId, rttTextStream);
1485 } finally {
1486 args.recycle();
1487 Log.endSession();
1488 }
1489 break;
1490 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001491 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1492 onConnectionServiceFocusGained();
1493 break;
1494 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1495 onConnectionServiceFocusLost();
1496 break;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001497 default:
1498 break;
1499 }
1500 }
1501 };
1502
Santos Cordon823fd3c2014-08-07 18:35:18 -07001503 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1504 @Override
1505 public void onStateChanged(Conference conference, int oldState, int newState) {
1506 String id = mIdByConference.get(conference);
1507 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301508 case Connection.STATE_RINGING:
1509 mAdapter.setRinging(id);
1510 break;
1511 case Connection.STATE_DIALING:
1512 mAdapter.setDialing(id);
1513 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001514 case Connection.STATE_ACTIVE:
1515 mAdapter.setActive(id);
1516 break;
1517 case Connection.STATE_HOLDING:
1518 mAdapter.setOnHold(id);
1519 break;
1520 case Connection.STATE_DISCONNECTED:
1521 // handled by onDisconnected
1522 break;
1523 }
1524 }
1525
1526 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001527 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001528 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001529 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001530 }
1531
1532 @Override
1533 public void onConnectionAdded(Conference conference, Connection connection) {
1534 }
1535
1536 @Override
1537 public void onConnectionRemoved(Conference conference, Connection connection) {
1538 }
1539
1540 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001541 public void onConferenceableConnectionsChanged(
1542 Conference conference, List<Connection> conferenceableConnections) {
1543 mAdapter.setConferenceableConnections(
1544 mIdByConference.get(conference),
1545 createConnectionIdList(conferenceableConnections));
1546 }
1547
1548 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001549 public void onDestroyed(Conference conference) {
1550 removeConference(conference);
1551 }
1552
1553 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001554 public void onConnectionCapabilitiesChanged(
1555 Conference conference,
1556 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001557 String id = mIdByConference.get(conference);
1558 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001559 Connection.capabilitiesToString(connectionCapabilities));
1560 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001561 }
Rekha Kumar07366812015-03-24 16:42:31 -07001562
1563 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001564 public void onConnectionPropertiesChanged(
1565 Conference conference,
1566 int connectionProperties) {
1567 String id = mIdByConference.get(conference);
1568 Log.d(this, "call capabilities: conference: %s",
1569 Connection.propertiesToString(connectionProperties));
1570 mAdapter.setConnectionProperties(id, connectionProperties);
1571 }
1572
1573 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001574 public void onVideoStateChanged(Conference c, int videoState) {
1575 String id = mIdByConference.get(c);
1576 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1577 mAdapter.setVideoState(id, videoState);
1578 }
1579
1580 @Override
1581 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1582 String id = mIdByConference.get(c);
1583 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1584 videoProvider);
1585 mAdapter.setVideoProvider(id, videoProvider);
1586 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001587
1588 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001589 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1590 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001591 if (id != null) {
1592 mAdapter.setStatusHints(id, statusHints);
1593 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001594 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001595
1596 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001597 public void onExtrasChanged(Conference c, Bundle extras) {
1598 String id = mIdByConference.get(c);
1599 if (id != null) {
1600 mAdapter.putExtras(id, extras);
1601 }
1602 }
1603
1604 @Override
1605 public void onExtrasRemoved(Conference c, List<String> keys) {
1606 String id = mIdByConference.get(c);
1607 if (id != null) {
1608 mAdapter.removeExtras(id, keys);
1609 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001610 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001611
1612 @Override
1613 public void onConferenceStateChanged(Conference c, boolean isConference) {
1614 String id = mIdByConference.get(c);
1615 if (id != null) {
1616 mAdapter.setConferenceState(id, isConference);
1617 }
1618 }
1619
1620 @Override
Brad Ebingere0c12f42020-04-08 16:25:12 -07001621 public void onCallDirectionChanged(Conference c, int direction) {
1622 String id = mIdByConference.get(c);
1623 if (id != null) {
1624 mAdapter.setCallDirection(id, direction);
1625 }
1626 }
1627
1628 @Override
Tyler Gunn68a73a42018-10-03 15:38:57 -07001629 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1630 String id = mIdByConference.get(c);
1631 if (id != null) {
1632 mAdapter.setAddress(id, newAddress, presentation);
1633 }
1634 }
1635
1636 @Override
1637 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1638 int presentation) {
1639 String id = mIdByConference.get(c);
1640 if (id != null) {
1641 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1642 }
1643 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001644
1645 @Override
1646 public void onConnectionEvent(Conference c, String event, Bundle extras) {
1647 String id = mIdByConference.get(c);
1648 if (id != null) {
1649 mAdapter.onConnectionEvent(id, event, extras);
1650 }
1651 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301652
1653 @Override
1654 public void onRingbackRequested(Conference c, boolean ringback) {
1655 String id = mIdByConference.get(c);
1656 Log.d(this, "Adapter conference onRingback %b", ringback);
1657 mAdapter.setRingbackRequested(id, ringback);
1658 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001659 };
1660
Ihab Awad542e0ea2014-05-16 10:22:16 -07001661 private final Connection.Listener mConnectionListener = new Connection.Listener() {
1662 @Override
1663 public void onStateChanged(Connection c, int state) {
1664 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07001665 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001666 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001667 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001668 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001669 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001670 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001671 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001672 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001673 case Connection.STATE_PULLING_CALL:
1674 mAdapter.setPulling(id);
1675 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001676 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001677 // Handled in onDisconnected()
1678 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001679 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001680 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001681 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001682 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001683 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07001684 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001685 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001686 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001687 break;
1688 }
1689 }
1690
1691 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001692 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07001693 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07001694 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001695 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001696 }
1697
1698 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07001699 public void onVideoStateChanged(Connection c, int videoState) {
1700 String id = mIdByConnection.get(c);
1701 Log.d(this, "Adapter set video state %d", videoState);
1702 mAdapter.setVideoState(id, videoState);
1703 }
1704
1705 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001706 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001707 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001708 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07001709 }
1710
1711 @Override
1712 public void onCallerDisplayNameChanged(
1713 Connection c, String callerDisplayName, int presentation) {
1714 String id = mIdByConnection.get(c);
1715 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001716 }
1717
1718 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07001719 public void onDestroyed(Connection c) {
1720 removeConnection(c);
1721 }
Ihab Awadf8358972014-05-28 16:46:42 -07001722
1723 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001724 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07001725 String id = mIdByConnection.get(c);
1726 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001727 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001728 }
1729
1730 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001731 public void onPostDialChar(Connection c, char nextChar) {
1732 String id = mIdByConnection.get(c);
1733 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
1734 mAdapter.onPostDialChar(id, nextChar);
1735 }
1736
1737 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001738 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07001739 String id = mIdByConnection.get(c);
1740 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07001741 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07001742 }
Santos Cordonb6939982014-06-04 20:20:58 -07001743
1744 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001745 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07001746 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001747 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001748 Connection.capabilitiesToString(capabilities));
1749 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07001750 }
1751
Santos Cordonb6939982014-06-04 20:20:58 -07001752 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001753 public void onConnectionPropertiesChanged(Connection c, int properties) {
1754 String id = mIdByConnection.get(c);
1755 Log.d(this, "properties: parcelableconnection: %s",
1756 Connection.propertiesToString(properties));
1757 mAdapter.setConnectionProperties(id, properties);
1758 }
1759
1760 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001761 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001762 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07001763 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1764 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001765 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001766 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001767
1768 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001769 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001770 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001771 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001772 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001773
1774 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001775 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001776 String id = mIdByConnection.get(c);
1777 mAdapter.setStatusHints(id, statusHints);
1778 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001779
1780 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001781 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001782 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001783 mAdapter.setConferenceableConnections(
1784 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001785 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001786 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001787
1788 @Override
1789 public void onConferenceChanged(Connection connection, Conference conference) {
1790 String id = mIdByConnection.get(connection);
1791 if (id != null) {
1792 String conferenceId = null;
1793 if (conference != null) {
1794 conferenceId = mIdByConference.get(conference);
1795 }
1796 mAdapter.setIsConferenced(id, conferenceId);
1797 }
1798 }
Anthony Lee17455a32015-04-24 15:25:29 -07001799
1800 @Override
1801 public void onConferenceMergeFailed(Connection connection) {
1802 String id = mIdByConnection.get(connection);
1803 if (id != null) {
1804 mAdapter.onConferenceMergeFailed(id);
1805 }
1806 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001807
1808 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001809 public void onExtrasChanged(Connection c, Bundle extras) {
1810 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001811 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07001812 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001813 }
1814 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001815
Tyler Gunnf5035432017-01-09 09:43:12 -08001816 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001817 public void onExtrasRemoved(Connection c, List<String> keys) {
1818 String id = mIdByConnection.get(c);
1819 if (id != null) {
1820 mAdapter.removeExtras(id, keys);
1821 }
1822 }
1823
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001824 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001825 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001826 String id = mIdByConnection.get(connection);
1827 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001828 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001829 }
1830 }
Tyler Gunnf5035432017-01-09 09:43:12 -08001831
1832 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08001833 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001834 String id = mIdByConnection.get(c);
1835 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08001836 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08001837 }
1838 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001839
1840 @Override
1841 public void onRttInitiationSuccess(Connection c) {
1842 String id = mIdByConnection.get(c);
1843 if (id != null) {
1844 mAdapter.onRttInitiationSuccess(id);
1845 }
1846 }
1847
1848 @Override
1849 public void onRttInitiationFailure(Connection c, int reason) {
1850 String id = mIdByConnection.get(c);
1851 if (id != null) {
1852 mAdapter.onRttInitiationFailure(id, reason);
1853 }
1854 }
1855
1856 @Override
1857 public void onRttSessionRemotelyTerminated(Connection c) {
1858 String id = mIdByConnection.get(c);
1859 if (id != null) {
1860 mAdapter.onRttSessionRemotelyTerminated(id);
1861 }
1862 }
1863
1864 @Override
1865 public void onRemoteRttRequest(Connection c) {
1866 String id = mIdByConnection.get(c);
1867 if (id != null) {
1868 mAdapter.onRemoteRttRequest(id);
1869 }
1870 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05301871
1872 @Override
1873 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
1874 String id = mIdByConnection.get(c);
1875 if (id != null) {
1876 mAdapter.onPhoneAccountChanged(id, pHandle);
1877 }
1878 }
Mengjun Leng25707742017-07-04 11:10:37 +08001879
1880 public void onConnectionTimeReset(Connection c) {
1881 String id = mIdByConnection.get(c);
1882 if (id != null) {
1883 mAdapter.resetConnectionTime(id);
1884 }
1885 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001886 };
1887
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001888 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07001889 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001890 public final IBinder onBind(Intent intent) {
Hall Liueb7c9ea2021-03-09 20:24:50 -08001891 onBindClient(intent);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001892 return mBinder;
1893 }
1894
Santos Cordon29f2f2e2014-09-11 19:50:24 -07001895 /** {@inheritDoc} */
1896 @Override
1897 public boolean onUnbind(Intent intent) {
1898 endAllConnections();
1899 return super.onUnbind(intent);
1900 }
1901
Hall Liueb7c9ea2021-03-09 20:24:50 -08001902 /**
1903 * Used for testing to let the test suite know when the connection service has been bound.
1904 * @hide
1905 */
1906 @TestApi
1907 public void onBindClient(@Nullable Intent intent) {
1908 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301909
1910 /**
1911 * This can be used by telecom to either create a new outgoing conference call or attach
1912 * to an existing incoming conference call. In either case, telecom will cycle through a
1913 * set of services and call createConference until a connection service cancels the process
1914 * or completes it successfully.
1915 */
1916 private void createConference(
1917 final PhoneAccountHandle callManagerAccount,
1918 final String callId,
1919 final ConnectionRequest request,
1920 boolean isIncoming,
1921 boolean isUnknown) {
1922
1923 Conference conference = null;
1924 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
1925 : onCreateOutgoingConference(callManagerAccount, request);
1926
1927 Log.d(this, "createConference, conference: %s", conference);
1928 if (conference == null) {
1929 Log.i(this, "createConference, implementation returned null conference.");
1930 conference = Conference.createFailedConference(
1931 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
1932 request.getAccountHandle());
1933 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001934
1935 Bundle extras = request.getExtras();
1936 Bundle newExtras = new Bundle();
1937 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
1938 if (extras != null) {
1939 // If the request originated from a remote connection service, we will add some
1940 // tracking information that Telecom can use to keep informed of which package
1941 // made the remote request, and which remote connection service was used.
1942 if (extras.containsKey(Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
1943 newExtras.putString(
1944 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
1945 extras.getString(
1946 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME));
1947 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
1948 request.getAccountHandle());
1949 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301950 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001951 conference.putExtras(newExtras);
1952
Ravi Paluri80aa2142019-12-02 11:57:37 +05301953 mConferenceById.put(callId, conference);
1954 mIdByConference.put(conference, callId);
Tyler Gunn460360d2020-07-29 10:21:45 -07001955
Ravi Paluri80aa2142019-12-02 11:57:37 +05301956 conference.addListener(mConferenceListener);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07001957 ParcelableConference parcelableConference = new ParcelableConference.Builder(
1958 request.getAccountHandle(), conference.getState())
1959 .setConnectionCapabilities(conference.getConnectionCapabilities())
1960 .setConnectionProperties(conference.getConnectionProperties())
1961 .setVideoAttributes(conference.getVideoProvider() == null
1962 ? null : conference.getVideoProvider().getInterface(),
1963 conference.getVideoState())
1964 .setConnectTimeMillis(conference.getConnectTimeMillis(),
1965 conference.getConnectionStartElapsedRealtimeMillis())
1966 .setStatusHints(conference.getStatusHints())
1967 .setExtras(conference.getExtras())
1968 .setAddress(conference.getAddress(), conference.getAddressPresentation())
1969 .setCallerDisplayName(conference.getCallerDisplayName(),
1970 conference.getCallerDisplayNamePresentation())
1971 .setDisconnectCause(conference.getDisconnectCause())
1972 .setRingbackRequested(conference.isRingbackRequested())
1973 .build();
Ravi Paluri80aa2142019-12-02 11:57:37 +05301974 if (conference.getState() != Connection.STATE_DISCONNECTED) {
1975 conference.setTelecomCallId(callId);
1976 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
1977 mAdapter.setVideoState(callId, conference.getVideoState());
1978 onConferenceAdded(conference);
1979 }
1980
1981 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
1982 mAdapter.handleCreateConferenceComplete(
1983 callId,
1984 request,
1985 parcelableConference);
1986 }
1987
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001988 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001989 * This can be used by telecom to either create a new outgoing call or attach to an existing
1990 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001991 * createConnection util a connection service cancels the process or completes it successfully.
1992 */
Ihab Awadf8b69882014-07-25 15:14:01 -07001993 private void createConnection(
1994 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001995 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07001996 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07001997 boolean isIncoming,
1998 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001999 boolean isLegacyHandover = request.getExtras() != null &&
2000 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
2001 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
2002 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Grace Jia4e8dc102021-01-19 14:58:01 -08002003 boolean addSelfManaged = request.getExtras() != null && request.getExtras().getBoolean(
Grace Jia8b22bb42021-02-02 15:37:32 -08002004 PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
Grace Jia4e8dc102021-01-19 14:58:01 -08002005 Log.i(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, "
2006 + "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b, "
2007 + " addSelfManaged: %b", callManagerAccount, callId, request, isIncoming,
2008 isUnknown, isLegacyHandover, isHandover, addSelfManaged);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002009
Sanket Padawee29a2662017-12-01 13:59:27 -08002010 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002011 if (isHandover) {
2012 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
2013 ? (PhoneAccountHandle) request.getExtras().getParcelable(
2014 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08002015 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002016 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002017 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002018 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002019 }
2020 } else {
2021 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
2022 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
2023 : onCreateOutgoingConnection(callManagerAccount, request);
2024 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002025 Log.d(this, "createConnection, connection: %s", connection);
2026 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002027 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002028 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002029 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002030 } else {
2031 try {
2032 Bundle extras = request.getExtras();
2033 if (extras != null) {
2034 // If the request originated from a remote connection service, we will add some
2035 // tracking information that Telecom can use to keep informed of which package
2036 // made the remote request, and which remote connection service was used.
2037 if (extras.containsKey(
2038 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2039 Bundle newExtras = new Bundle();
2040 newExtras.putString(
2041 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2042 extras.getString(
2043 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME
2044 ));
2045 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2046 request.getAccountHandle());
2047 connection.putExtras(newExtras);
2048 }
2049 }
2050 } catch (UnsupportedOperationException ose) {
2051 // Do nothing; if the ConnectionService reported a failure it will be an instance
2052 // of an immutable Connection which we cannot edit, so we're out of luck.
2053 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002054 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002055
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002056 boolean isSelfManaged =
2057 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
2058 == Connection.PROPERTY_SELF_MANAGED;
2059 // Self-managed Connections should always use voip audio mode; we default here so that the
2060 // local state within the ConnectionService matches the default we assume in Telecom.
2061 if (isSelfManaged) {
2062 connection.setAudioModeIsVoip(true);
2063 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002064 connection.setTelecomCallId(callId);
Sungjae7f4137452020-09-16 17:01:54 +09002065 PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
2066 ? request.getAccountHandle() : connection.getPhoneAccountHandle();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002067 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Sungjae7f4137452020-09-16 17:01:54 +09002068 addConnection(phoneAccountHandle, callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07002069 }
2070
Andrew Lee100e2932014-09-08 15:34:24 -07002071 Uri address = connection.getAddress();
2072 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07002073 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002074 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002075 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07002076 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
2077 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002078
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002079 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07002080 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002081 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07002082 request,
2083 new ParcelableConnection(
Sungjae7f4137452020-09-16 17:01:54 +09002084 phoneAccountHandle,
Evan Charltonbf11f982014-07-20 22:06:28 -07002085 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002086 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002087 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002088 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07002089 connection.getAddress(),
2090 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07002091 connection.getCallerDisplayName(),
2092 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002093 connection.getVideoProvider() == null ?
2094 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002095 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07002096 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002097 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002098 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002099 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07002100 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002101 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002102 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002103 connection.getExtras(),
2104 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08002105
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002106 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002107 // Tell ConnectionService to show its incoming call UX.
2108 connection.onShowIncomingCallUi();
2109 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002110 if (isUnknown) {
2111 triggerConferenceRecalculate();
2112 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002113 }
2114
Tyler Gunn159f35c2017-03-02 09:28:37 -08002115 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
2116 final String callId, final ConnectionRequest request,
2117 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08002118
2119 Log.i(this, "createConnectionFailed %s", callId);
2120 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002121 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002122 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002123 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002124 }
2125 }
2126
Ravi Paluri80aa2142019-12-02 11:57:37 +05302127 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
2128 final String callId, final ConnectionRequest request,
2129 boolean isIncoming) {
2130
2131 Log.i(this, "createConferenceFailed %s", callId);
2132 if (isIncoming) {
2133 onCreateIncomingConferenceFailed(callManagerAccount, request);
2134 } else {
2135 onCreateOutgoingConferenceFailed(callManagerAccount, request);
2136 }
2137 }
2138
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08002139 private void handoverFailed(final String callId, final ConnectionRequest request,
2140 int reason) {
2141
2142 Log.i(this, "handoverFailed %s", callId);
2143 onHandoverFailed(request, reason);
2144 }
2145
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002146 /**
2147 * Called by Telecom when the creation of a new Connection has completed and it is now added
2148 * to Telecom.
2149 * @param callId The ID of the connection.
2150 */
2151 private void notifyCreateConnectionComplete(final String callId) {
2152 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07002153 if (callId == null) {
2154 // This could happen if the connection fails quickly and is removed from the
2155 // ConnectionService before Telecom sends the create connection complete callback.
2156 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
2157 return;
2158 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002159 onCreateConnectionComplete(findConnectionForAction(callId,
2160 "notifyCreateConnectionComplete"));
2161 }
2162
Ravi Paluri80aa2142019-12-02 11:57:37 +05302163 /**
2164 * Called by Telecom when the creation of a new Conference has completed and it is now added
2165 * to Telecom.
2166 * @param callId The ID of the connection.
2167 */
2168 private void notifyCreateConferenceComplete(final String callId) {
2169 Log.i(this, "notifyCreateConferenceComplete %s", callId);
2170 if (callId == null) {
2171 // This could happen if the conference fails quickly and is removed from the
2172 // ConnectionService before Telecom sends the create conference complete callback.
2173 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
2174 return;
2175 }
2176 onCreateConferenceComplete(findConferenceForAction(callId,
2177 "notifyCreateConferenceComplete"));
2178 }
2179
2180
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002181 private void abort(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002182 Log.i(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002183 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002184 }
2185
Tyler Gunnbe74de02014-08-29 14:51:48 -07002186 private void answerVideo(String callId, int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002187 Log.i(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302188 if (mConnectionById.containsKey(callId)) {
2189 findConnectionForAction(callId, "answer").onAnswer(videoState);
2190 } else {
2191 findConferenceForAction(callId, "answer").onAnswer(videoState);
2192 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002193 }
2194
Tyler Gunnbe74de02014-08-29 14:51:48 -07002195 private void answer(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002196 Log.i(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302197 if (mConnectionById.containsKey(callId)) {
2198 findConnectionForAction(callId, "answer").onAnswer();
2199 } else {
2200 findConferenceForAction(callId, "answer").onAnswer();
2201 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002202 }
2203
Pooja Jaind34698d2017-12-28 14:15:31 +05302204 private void deflect(String callId, Uri address) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002205 Log.i(this, "deflect %s", callId);
Pooja Jaind34698d2017-12-28 14:15:31 +05302206 findConnectionForAction(callId, "deflect").onDeflect(address);
2207 }
2208
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002209 private void reject(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002210 Log.i(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302211 if (mConnectionById.containsKey(callId)) {
2212 findConnectionForAction(callId, "reject").onReject();
2213 } else {
2214 findConferenceForAction(callId, "reject").onReject();
2215 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002216 }
2217
Bryce Lee81901682015-08-28 16:38:02 -07002218 private void reject(String callId, String rejectWithMessage) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002219 Log.i(this, "reject %s with message", callId);
Bryce Lee81901682015-08-28 16:38:02 -07002220 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2221 }
2222
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002223 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002224 Log.i(this, "reject %s with reason %d", callId, rejectReason);
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002225 findConnectionForAction(callId, "reject").onReject(rejectReason);
2226 }
2227
Ravi Palurif4b38e72020-02-05 12:35:41 +05302228 private void transfer(String callId, Uri number, boolean isConfirmationRequired) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002229 Log.i(this, "transfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302230 findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired);
2231 }
2232
2233 private void consultativeTransfer(String callId, String otherCallId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002234 Log.i(this, "consultativeTransfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302235 Connection connection1 = findConnectionForAction(callId, "consultativeTransfer");
2236 Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer");
2237 connection1.onTransfer(connection2);
2238 }
2239
Bryce Leecac50772015-11-17 15:13:29 -08002240 private void silence(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002241 Log.i(this, "silence %s", callId);
Bryce Leecac50772015-11-17 15:13:29 -08002242 findConnectionForAction(callId, "silence").onSilence();
2243 }
2244
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002245 private void disconnect(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002246 Log.i(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002247 if (mConnectionById.containsKey(callId)) {
2248 findConnectionForAction(callId, "disconnect").onDisconnect();
2249 } else {
2250 findConferenceForAction(callId, "disconnect").onDisconnect();
2251 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002252 }
2253
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002254 private void hold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002255 Log.i(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002256 if (mConnectionById.containsKey(callId)) {
2257 findConnectionForAction(callId, "hold").onHold();
2258 } else {
2259 findConferenceForAction(callId, "hold").onHold();
2260 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002261 }
2262
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002263 private void unhold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002264 Log.i(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002265 if (mConnectionById.containsKey(callId)) {
2266 findConnectionForAction(callId, "unhold").onUnhold();
2267 } else {
2268 findConferenceForAction(callId, "unhold").onUnhold();
2269 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002270 }
2271
Yorke Lee4af59352015-05-13 14:14:54 -07002272 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002273 Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002274 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002275 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2276 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002277 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002278 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2279 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002280 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002281 }
2282
Grace Jia4e8dc102021-01-19 14:58:01 -08002283 private void onUsingAlternativeUi(String callId, boolean isUsingAlternativeUi) {
2284 Log.i(this, "onUsingAlternativeUi %s %s", callId, isUsingAlternativeUi);
2285 if (mConnectionById.containsKey(callId)) {
2286 findConnectionForAction(callId, "onUsingAlternativeUi")
2287 .onUsingAlternativeUi(isUsingAlternativeUi);
2288 }
2289 }
2290
2291 private void onTrackedByNonUiService(String callId, boolean isTracked) {
2292 Log.i(this, "onTrackedByNonUiService %s %s", callId, isTracked);
2293 if (mConnectionById.containsKey(callId)) {
2294 findConnectionForAction(callId, "onTrackedByNonUiService")
2295 .onTrackedByNonUiService(isTracked);
2296 }
2297 }
2298
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002299 private void playDtmfTone(String callId, char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002300 Log.i(this, "playDtmfTone %s %c", callId, digit);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002301 if (mConnectionById.containsKey(callId)) {
2302 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2303 } else {
2304 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2305 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002306 }
2307
2308 private void stopDtmfTone(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002309 Log.i(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002310 if (mConnectionById.containsKey(callId)) {
2311 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2312 } else {
2313 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2314 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002315 }
2316
Santos Cordon823fd3c2014-08-07 18:35:18 -07002317 private void conference(String callId1, String callId2) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002318 Log.i(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002319
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002320 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002321 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002322 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002323 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002324 conference2 = findConferenceForAction(callId2, "conference");
2325 if (conference2 == getNullConference()) {
2326 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2327 callId2);
2328 return;
2329 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002330 }
Santos Cordonb6939982014-06-04 20:20:58 -07002331
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002332 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002333 Connection connection1 = findConnectionForAction(callId1, "conference");
2334 if (connection1 == getNullConnection()) {
2335 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2336 if (conference1 == getNullConference()) {
2337 Log.w(this,
2338 "Connection1 or Conference1 missing in conference request %s.",
2339 callId1);
2340 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002341 // Call 1 is a conference.
2342 if (connection2 != getNullConnection()) {
2343 // Call 2 is a connection so merge via call 1 (conference).
2344 conference1.onMerge(connection2);
2345 } else {
2346 // Call 2 is ALSO a conference; this should never happen.
2347 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2348 "merge two conferences.");
2349 return;
2350 }
Ihab Awad50e35062014-09-30 09:17:03 -07002351 }
2352 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002353 // Call 1 is a connection.
2354 if (conference2 != getNullConference()) {
2355 // Call 2 is a conference, so merge via call 2.
2356 conference2.onMerge(connection1);
2357 } else {
2358 // Call 2 is a connection, so merge together.
2359 onConference(connection1, connection2);
2360 }
Ihab Awad50e35062014-09-30 09:17:03 -07002361 }
Santos Cordon980acb92014-05-31 10:31:19 -07002362 }
2363
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002364 private void splitFromConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002365 Log.i(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002366
2367 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002368 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002369 Log.w(this, "Connection missing in conference request %s.", callId);
2370 return;
2371 }
2372
Santos Cordon0159ac02014-08-21 14:28:11 -07002373 Conference conference = connection.getConference();
2374 if (conference != null) {
2375 conference.onSeparate(connection);
2376 }
Santos Cordon980acb92014-05-31 10:31:19 -07002377 }
2378
Santos Cordona4868042014-09-04 17:39:22 -07002379 private void mergeConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002380 Log.i(this, "mergeConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002381 Conference conference = findConferenceForAction(callId, "mergeConference");
2382 if (conference != null) {
2383 conference.onMerge();
2384 }
2385 }
2386
2387 private void swapConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002388 Log.i(this, "swapConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002389 Conference conference = findConferenceForAction(callId, "swapConference");
2390 if (conference != null) {
2391 conference.onSwap();
2392 }
2393 }
2394
Ravi Paluri404babb2020-01-23 19:02:44 +05302395 private void addConferenceParticipants(String callId, List<Uri> participants) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002396 Log.i(this, "addConferenceParticipants(%s)", callId);
Ravi Paluri404babb2020-01-23 19:02:44 +05302397 if (mConnectionById.containsKey(callId)) {
2398 findConnectionForAction(callId, "addConferenceParticipants")
2399 .onAddConferenceParticipants(participants);
2400 } else {
2401 findConferenceForAction(callId, "addConferenceParticipants")
2402 .onAddConferenceParticipants(participants);
2403 }
2404 }
2405
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002406 /**
2407 * Notifies a {@link Connection} of a request to pull an external call.
2408 *
2409 * See {@link Call#pullExternalCall()}.
2410 *
2411 * @param callId The ID of the call to pull.
2412 */
2413 private void pullExternalCall(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002414 Log.i(this, "pullExternalCall(%s)", callId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002415 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2416 if (connection != null) {
2417 connection.onPullExternalCall();
2418 }
2419 }
2420
2421 /**
2422 * Notifies a {@link Connection} of a call event.
2423 *
2424 * See {@link Call#sendCallEvent(String, Bundle)}.
2425 *
2426 * @param callId The ID of the call receiving the event.
2427 * @param event The event.
2428 * @param extras Extras associated with the event.
2429 */
2430 private void sendCallEvent(String callId, String event, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002431 Log.i(this, "sendCallEvent(%s, %s)", callId, event);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002432 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2433 if (connection != null) {
2434 connection.onCallEvent(event, extras);
2435 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002436 }
2437
Tyler Gunndee56a82016-03-23 16:06:34 -07002438 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002439 * Notifies a {@link Connection} that a handover has completed.
2440 *
2441 * @param callId The ID of the call which completed handover.
2442 */
2443 private void notifyHandoverComplete(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002444 Log.i(this, "notifyHandoverComplete(%s)", callId);
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002445 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2446 if (connection != null) {
2447 connection.onHandoverComplete();
2448 }
2449 }
2450
2451 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002452 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2453 * <p>
2454 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2455 * the {@link android.telecom.Call#putExtra(String, boolean)},
2456 * {@link android.telecom.Call#putExtra(String, int)},
2457 * {@link android.telecom.Call#putExtra(String, String)},
2458 * {@link Call#removeExtras(List)}.
2459 *
2460 * @param callId The ID of the call receiving the event.
2461 * @param extras The new extras bundle.
2462 */
2463 private void handleExtrasChanged(String callId, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002464 Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002465 if (mConnectionById.containsKey(callId)) {
2466 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2467 } else if (mConferenceById.containsKey(callId)) {
2468 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2469 }
2470 }
2471
Hall Liub64ac4c2017-02-06 10:49:48 -08002472 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002473 Log.i(this, "startRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002474 if (mConnectionById.containsKey(callId)) {
2475 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2476 } else if (mConferenceById.containsKey(callId)) {
2477 Log.w(this, "startRtt called on a conference.");
2478 }
2479 }
2480
2481 private void stopRtt(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002482 Log.i(this, "stopRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002483 if (mConnectionById.containsKey(callId)) {
2484 findConnectionForAction(callId, "stopRtt").onStopRtt();
2485 } else if (mConferenceById.containsKey(callId)) {
2486 Log.w(this, "stopRtt called on a conference.");
2487 }
2488 }
2489
2490 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002491 Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
Hall Liub64ac4c2017-02-06 10:49:48 -08002492 if (mConnectionById.containsKey(callId)) {
2493 findConnectionForAction(callId, "handleRttUpgradeResponse")
2494 .handleRttUpgradeResponse(rttTextStream);
2495 } else if (mConferenceById.containsKey(callId)) {
2496 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2497 }
2498 }
2499
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002500 private void onPostDialContinue(String callId, boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002501 Log.i(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002502 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002503 }
2504
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002505 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002506 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002507 // No need to query again if we already did it.
2508 return;
2509 }
2510
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002511 String callingPackage = getOpPackageName();
2512
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002513 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002514 @Override
2515 public void onResult(
2516 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002517 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002518 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002519 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002520 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002521 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002522 mRemoteConnectionManager.addConnectionService(
2523 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002524 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002525 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002526 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002527 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002528 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002529 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002530 }
2531
2532 @Override
2533 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002534 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002535 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002536 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002537 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002538 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002539 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002540 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002541 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002542 }
2543
Ihab Awadf8b69882014-07-25 15:14:01 -07002544 /**
2545 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002546 * incoming request. This is used by {@code ConnectionService}s that are registered with
2547 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2548 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002549 *
2550 * @param connectionManagerPhoneAccount See description at
2551 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2552 * @param request Details about the incoming call.
2553 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2554 * not handle the call.
2555 */
2556 public final RemoteConnection createRemoteIncomingConnection(
2557 PhoneAccountHandle connectionManagerPhoneAccount,
2558 ConnectionRequest request) {
2559 return mRemoteConnectionManager.createRemoteConnection(
2560 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002561 }
2562
2563 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002564 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002565 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2566 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2567 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002568 *
2569 * @param connectionManagerPhoneAccount See description at
2570 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002571 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002572 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2573 * not handle the call.
2574 */
2575 public final RemoteConnection createRemoteOutgoingConnection(
2576 PhoneAccountHandle connectionManagerPhoneAccount,
2577 ConnectionRequest request) {
2578 return mRemoteConnectionManager.createRemoteConnection(
2579 connectionManagerPhoneAccount, request, false);
2580 }
2581
2582 /**
Grace Jia9a09c672020-08-04 12:52:09 -07002583 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2584 * incoming request. This is used by {@code ConnectionService}s that are registered with
2585 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2586 *
2587 * @param connectionManagerPhoneAccount See description at
2588 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2589 * @param request Details about the incoming conference call.
2590 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2591 * handle the call.
2592 */
2593 public final @Nullable RemoteConference createRemoteIncomingConference(
2594 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2595 @Nullable ConnectionRequest request) {
2596 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2597 request, true);
2598 }
2599
2600 /**
2601 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2602 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2603 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2604 *
2605 * @param connectionManagerPhoneAccount See description at
2606 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2607 * @param request Details about the outgoing conference call.
2608 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2609 * handle the call.
2610 */
2611 public final @Nullable RemoteConference createRemoteOutgoingConference(
2612 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2613 @Nullable ConnectionRequest request) {
2614 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2615 request, false);
2616 }
2617
2618 /**
Santos Cordona663f862014-10-29 13:49:58 -07002619 * Indicates to the relevant {@code RemoteConnectionService} that the specified
2620 * {@link RemoteConnection}s should be merged into a conference call.
2621 * <p>
2622 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
2623 * be invoked.
2624 *
2625 * @param remoteConnection1 The first of the remote connections to conference.
2626 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07002627 */
2628 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07002629 RemoteConnection remoteConnection1,
2630 RemoteConnection remoteConnection2) {
2631 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07002632 }
2633
2634 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002635 * Adds a new conference call. When a conference call is created either as a result of an
2636 * explicit request via {@link #onConference} or otherwise, the connection service should supply
2637 * an instance of {@link Conference} by invoking this method. A conference call provided by this
2638 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
2639 *
2640 * @param conference The new conference object.
2641 */
2642 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07002643 Log.d(this, "addConference: conference=%s", conference);
2644
Santos Cordon823fd3c2014-08-07 18:35:18 -07002645 String id = addConferenceInternal(conference);
2646 if (id != null) {
2647 List<String> connectionIds = new ArrayList<>(2);
2648 for (Connection connection : conference.getConnections()) {
2649 if (mIdByConnection.containsKey(connection)) {
2650 connectionIds.add(mIdByConnection.get(connection));
2651 }
2652 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002653 conference.setTelecomCallId(id);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07002654 ParcelableConference parcelableConference = new ParcelableConference.Builder(
2655 conference.getPhoneAccountHandle(), conference.getState())
2656 .setConnectionCapabilities(conference.getConnectionCapabilities())
2657 .setConnectionProperties(conference.getConnectionProperties())
2658 .setConnectionIds(connectionIds)
2659 .setVideoAttributes(conference.getVideoProvider() == null
2660 ? null : conference.getVideoProvider().getInterface(),
2661 conference.getVideoState())
2662 .setConnectTimeMillis(conference.getConnectTimeMillis(),
2663 conference.getConnectionStartElapsedRealtimeMillis())
2664 .setStatusHints(conference.getStatusHints())
2665 .setExtras(conference.getExtras())
2666 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2667 .setCallerDisplayName(conference.getCallerDisplayName(),
2668 conference.getCallerDisplayNamePresentation())
2669 .setDisconnectCause(conference.getDisconnectCause())
2670 .setRingbackRequested(conference.isRingbackRequested())
2671 .setCallDirection(conference.getCallDirection())
2672 .build();
Andrew Lee0f51da32015-04-16 13:11:55 -07002673
Santos Cordon823fd3c2014-08-07 18:35:18 -07002674 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07002675 mAdapter.setVideoProvider(id, conference.getVideoProvider());
2676 mAdapter.setVideoState(id, conference.getVideoState());
Tyler Gunn10362372020-04-08 13:12:30 -07002677 // In some instances a conference can start its life as a standalone call with just a
2678 // single participant; ensure we signal to Telecom in this case.
2679 if (!conference.isMultiparty()) {
2680 mAdapter.setConferenceState(id, conference.isMultiparty());
2681 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002682
2683 // Go through any child calls and set the parent.
2684 for (Connection connection : conference.getConnections()) {
2685 String connectionId = mIdByConnection.get(connection);
2686 if (connectionId != null) {
2687 mAdapter.setIsConferenced(connectionId, id);
2688 }
2689 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002690 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002691 }
2692 }
2693
2694 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002695 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
2696 * connection.
2697 *
2698 * @param phoneAccountHandle The phone account handle for the connection.
2699 * @param connection The connection to add.
2700 */
2701 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
2702 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07002703 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
2704 }
2705
2706 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002707 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
2708 * microphone, camera).
2709 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08002710 * <p>
2711 * The {@link ConnectionService} will be disconnected when it failed to call this method within
2712 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
2713 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08002714 * @see ConnectionService#onConnectionServiceFocusLost()
2715 */
2716 public final void connectionServiceFocusReleased() {
2717 mAdapter.onConnectionServiceFocusReleased();
2718 }
2719
2720 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07002721 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07002722 * connection, as well as adding that connection to the specified conference.
2723 * <p>
2724 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
2725 * IMS conference participants to be added to a conference in a single step; this helps ensure
2726 * UI updates happen atomically, rather than adding the connection and then adding it to
2727 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07002728 *
2729 * @param phoneAccountHandle The phone account handle for the connection.
2730 * @param connection The connection to add.
2731 * @param conference The parent conference of the new connection.
2732 * @hide
2733 */
Tyler Gunn5567d742019-10-31 13:04:37 -07002734 @SystemApi
2735 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
2736 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002737
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002738 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002739 if (id != null) {
2740 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07002741 String conferenceId = null;
2742 if (conference != null) {
2743 conferenceId = mIdByConference.get(conference);
2744 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002745
2746 ParcelableConnection parcelableConnection = new ParcelableConnection(
2747 phoneAccountHandle,
2748 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002749 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002750 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002751 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002752 connection.getAddress(),
2753 connection.getAddressPresentation(),
2754 connection.getCallerDisplayName(),
2755 connection.getCallerDisplayNamePresentation(),
2756 connection.getVideoProvider() == null ?
2757 null : connection.getVideoProvider().getInterface(),
2758 connection.getVideoState(),
2759 connection.isRingbackRequested(),
2760 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002761 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002762 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002763 connection.getStatusHints(),
2764 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002765 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07002766 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07002767 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002768 connection.getCallDirection(),
2769 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002770 mAdapter.addExistingConnection(id, parcelableConnection);
2771 }
2772 }
2773
2774 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002775 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
2776 * has taken responsibility.
2777 *
2778 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07002779 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07002780 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07002781 return mConnectionById.values();
2782 }
2783
2784 /**
Santos Cordona6018b92016-02-16 14:23:12 -08002785 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
2786 * has taken responsibility.
2787 *
2788 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
2789 */
2790 public final Collection<Conference> getAllConferences() {
2791 return mConferenceById.values();
2792 }
2793
2794 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002795 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2796 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07002797 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002798 * @param connectionManagerPhoneAccount See description at
2799 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2800 * @param request Details about the incoming call.
2801 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2802 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002803 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002804 public Connection onCreateIncomingConnection(
2805 PhoneAccountHandle connectionManagerPhoneAccount,
2806 ConnectionRequest request) {
2807 return null;
2808 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302809 /**
Grace Jia8587ee52020-07-10 15:42:32 -07002810 * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
2811 * conference call initiated via
2812 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302813 *
2814 * @param connectionManagerPhoneAccount See description at
2815 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Grace Jia8587ee52020-07-10 15:42:32 -07002816 * @param request Details about the incoming conference call.
2817 * @return The {@code Conference} object to satisfy this call, or {@code null} to
Ravi Paluri80aa2142019-12-02 11:57:37 +05302818 * not handle the call.
2819 */
2820 public @Nullable Conference onCreateIncomingConference(
2821 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2822 @Nullable ConnectionRequest request) {
2823 return null;
2824 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002825
2826 /**
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002827 * Called after the {@link Connection} returned by
2828 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
2829 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
2830 * added to the {@link ConnectionService} and sent to Telecom.
2831 *
2832 * @param connection the {@link Connection}.
2833 * @hide
2834 */
2835 public void onCreateConnectionComplete(Connection connection) {
2836 }
2837
2838 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302839 * Called after the {@link Conference} returned by
2840 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
2841 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
2842 * added to the {@link ConnectionService} and sent to Telecom.
2843 *
2844 * @param conference the {@link Conference}.
2845 * @hide
2846 */
2847 public void onCreateConferenceComplete(Conference conference) {
2848 }
2849
2850
2851 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002852 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2853 * incoming {@link Connection} was denied.
2854 * <p>
2855 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2856 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
2857 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2858 * {@link Connection}.
2859 * <p>
2860 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2861 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002862 * @param connectionManagerPhoneAccount See description at
2863 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002864 * @param request The incoming connection request.
2865 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002866 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2867 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002868 }
2869
2870 /**
2871 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2872 * outgoing {@link Connection} was denied.
2873 * <p>
2874 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2875 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
2876 * The {@link ConnectionService} is responisible for informing the user that the
2877 * {@link Connection} cannot be made at this time.
2878 * <p>
2879 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2880 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002881 * @param connectionManagerPhoneAccount See description at
2882 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002883 * @param request The outgoing connection request.
2884 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002885 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2886 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002887 }
2888
2889 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302890 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2891 * incoming {@link Conference} was denied.
2892 * <p>
2893 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2894 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
2895 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2896 * {@link Conference}.
2897 * <p>
2898 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2899 *
2900 * @param connectionManagerPhoneAccount See description at
2901 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2902 * @param request The incoming connection request.
2903 */
2904 public void onCreateIncomingConferenceFailed(
2905 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2906 @Nullable ConnectionRequest request) {
2907 }
2908
2909 /**
2910 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2911 * outgoing {@link Conference} was denied.
2912 * <p>
2913 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2914 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
2915 * The {@link ConnectionService} is responisible for informing the user that the
2916 * {@link Conference} cannot be made at this time.
2917 * <p>
2918 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2919 *
2920 * @param connectionManagerPhoneAccount See description at
2921 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2922 * @param request The outgoing connection request.
2923 */
2924 public void onCreateOutgoingConferenceFailed(
2925 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2926 @Nullable ConnectionRequest request) {
2927 }
2928
2929
2930 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002931 * Trigger recalculate functinality for conference calls. This is used when a Telephony
2932 * Connection is part of a conference controller but is not yet added to Connection
2933 * Service and hence cannot be added to the conference call.
2934 *
2935 * @hide
2936 */
2937 public void triggerConferenceRecalculate() {
2938 }
2939
2940 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002941 * Create a {@code Connection} given an outgoing request. This is used to initiate new
2942 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002943 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002944 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2945 * this call.
2946 * <p>
2947 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2948 * has registered one or more {@code PhoneAccount}s having
2949 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2950 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2951 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2952 * making the connection.
2953 * <p>
2954 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2955 * being asked to make a direct connection. The
2956 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2957 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2958 * making the connection.
2959 * @param request Details about the outgoing call.
2960 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002961 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002962 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002963 public Connection onCreateOutgoingConnection(
2964 PhoneAccountHandle connectionManagerPhoneAccount,
2965 ConnectionRequest request) {
2966 return null;
2967 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002968
2969 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302970 * Create a {@code Conference} given an outgoing request. This is used to initiate new
Grace Jia8587ee52020-07-10 15:42:32 -07002971 * outgoing conference call requested via
2972 * {@link TelecomManager#startConference(List, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302973 *
2974 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2975 * this call.
2976 * <p>
2977 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2978 * has registered one or more {@code PhoneAccount}s having
2979 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2980 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2981 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2982 * making the connection.
2983 * <p>
2984 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2985 * being asked to make a direct connection. The
2986 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2987 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2988 * making the connection.
2989 * @param request Details about the outgoing call.
2990 * @return The {@code Conference} object to satisfy this call, or the result of an invocation
2991 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
2992 */
2993 public @Nullable Conference onCreateOutgoingConference(
2994 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2995 @Nullable ConnectionRequest request) {
2996 return null;
2997 }
2998
2999
3000 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003001 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3002 * outgoing handover {@link Connection}.
3003 * <p>
3004 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3005 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3006 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3007 * is referred to as the source of the handover, and the video calling app is referred to as the
3008 * destination.
3009 * <p>
3010 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3011 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3012 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3013 * device.
3014 * <p>
3015 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
3016 * device when the user initiates a handover request from one app to another. The user request
3017 * originates in the {@link InCallService} via
3018 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3019 * <p>
3020 * For a full discussion of the handover process and the APIs involved, see
3021 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3022 * <p>
3023 * Implementations of this method should return an instance of {@link Connection} which
3024 * represents the handover. If your app does not wish to accept a handover to it at this time,
3025 * you can return {@code null}. The code below shows an example of how this is done.
3026 * <pre>
3027 * {@code
3028 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3029 * fromPhoneAccountHandle, ConnectionRequest request) {
3030 * if (!isHandoverAvailable()) {
3031 * return null;
3032 * }
3033 * MyConnection connection = new MyConnection();
3034 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3035 * connection.setVideoState(request.getVideoState());
3036 * return connection;
3037 * }
3038 * }
3039 * </pre>
3040 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003041 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3042 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08003043 * @param request Details about the call to handover.
3044 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003045 */
3046 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3047 ConnectionRequest request) {
3048 return null;
3049 }
3050
3051 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003052 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3053 * incoming handover {@link Connection}.
3054 * <p>
3055 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3056 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3057 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3058 * is referred to as the source of the handover, and the video calling app is referred to as the
3059 * destination.
3060 * <p>
3061 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3062 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3063 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3064 * device.
3065 * <p>
3066 * This method is called on the destination app on the <em>receiving</em> device when the
3067 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
3068 * accept an incoming handover from the <em>initiating</em> device.
3069 * <p>
3070 * For a full discussion of the handover process and the APIs involved, see
3071 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3072 * <p>
3073 * Implementations of this method should return an instance of {@link Connection} which
3074 * represents the handover. The code below shows an example of how this is done.
3075 * <pre>
3076 * {@code
3077 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3078 * fromPhoneAccountHandle, ConnectionRequest request) {
3079 * // Given that your app requested to accept the handover, you should not return null here.
3080 * MyConnection connection = new MyConnection();
3081 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3082 * connection.setVideoState(request.getVideoState());
3083 * return connection;
3084 * }
3085 * }
3086 * </pre>
3087 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003088 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3089 * ConnectionService which needs to handover the call.
3090 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08003091 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003092 */
3093 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3094 ConnectionRequest request) {
3095 return null;
3096 }
3097
3098 /**
3099 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
3100 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08003101 * <p>
3102 * For a full discussion of the handover process and the APIs involved, see
3103 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
3104 *
3105 * @param request Details about the call which failed to handover.
3106 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07003107 */
Tyler Gunn9d127732018-03-02 15:45:51 -08003108 public void onHandoverFailed(ConnectionRequest request,
3109 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07003110 return;
3111 }
3112
3113 /**
Yorke Leec3cf9822014-10-02 09:38:39 -07003114 * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
3115 * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
3116 * call created using
3117 * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
3118 *
Yorke Lee770ed6e2014-10-06 18:58:52 -07003119 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07003120 */
3121 public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
3122 ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003123 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07003124 }
3125
3126 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003127 * Conference two specified connections. Invoked when the user has made a request to merge the
3128 * specified connections into a conference call. In response, the connection service should
3129 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07003130 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07003131 * @param connection1 A connection to merge into a conference call.
3132 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07003133 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07003134 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07003135
Santos Cordona663f862014-10-29 13:49:58 -07003136 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07003137 * Called when a connection is added.
3138 * @hide
3139 */
3140 public void onConnectionAdded(Connection connection) {}
3141
3142 /**
3143 * Called when a connection is removed.
3144 * @hide
3145 */
3146 public void onConnectionRemoved(Connection connection) {}
3147
3148 /**
3149 * Called when a conference is added.
3150 * @hide
3151 */
3152 public void onConferenceAdded(Conference conference) {}
3153
3154 /**
3155 * Called when a conference is removed.
3156 * @hide
3157 */
3158 public void onConferenceRemoved(Conference conference) {}
3159
3160 /**
Santos Cordona663f862014-10-29 13:49:58 -07003161 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
3162 * When this method is invoked, this {@link ConnectionService} should create its own
3163 * representation of the conference call and send it to telecom using {@link #addConference}.
3164 * <p>
3165 * This is only relevant to {@link ConnectionService}s which are registered with
3166 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
3167 *
3168 * @param conference The remote conference call.
3169 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07003170 public void onRemoteConferenceAdded(RemoteConference conference) {}
3171
Santos Cordon823fd3c2014-08-07 18:35:18 -07003172 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003173 * Called when an existing connection is added remotely.
3174 * @param connection The existing connection which was added.
3175 */
3176 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
3177
3178 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003179 * Called when the {@link ConnectionService} has lost the call focus.
3180 * The {@link ConnectionService} should release the call resources and invokes
3181 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
3182 * released the call resources.
3183 */
3184 public void onConnectionServiceFocusLost() {}
3185
3186 /**
3187 * Called when the {@link ConnectionService} has gained the call focus. The
3188 * {@link ConnectionService} can acquire the call resources at this time.
3189 */
3190 public void onConnectionServiceFocusGained() {}
3191
3192 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003193 * @hide
3194 */
3195 public boolean containsConference(Conference conference) {
3196 return mIdByConference.containsKey(conference);
3197 }
3198
Ihab Awadb8e85c72014-08-23 20:34:57 -07003199 /** {@hide} */
3200 void addRemoteConference(RemoteConference remoteConference) {
3201 onRemoteConferenceAdded(remoteConference);
3202 }
3203
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003204 /** {@hide} */
3205 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
3206 onRemoteExistingConnectionAdded(remoteConnection);
3207 }
3208
Ihab Awad5d0410f2014-07-30 10:07:40 -07003209 private void onAccountsInitialized() {
3210 mAreAccountsInitialized = true;
3211 for (Runnable r : mPreInitializationConnectionRequests) {
3212 r.run();
3213 }
3214 mPreInitializationConnectionRequests.clear();
3215 }
3216
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003217 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003218 * Adds an existing connection to the list of connections, identified by a new call ID unique
3219 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003220 *
3221 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003222 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003223 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003224 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
3225 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003226
3227 if (connection.getExtras() != null && connection.getExtras()
3228 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3229 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3230 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
3231 connection.getTelecomCallId(), id);
3232 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003233 // If no phone account handle was provided, we cannot be sure the call ID is unique,
3234 // so just use a random UUID.
3235 id = UUID.randomUUID().toString();
3236 } else {
3237 // Phone account handle was provided, so use the ConnectionService class name as a
3238 // prefix for a unique incremental call ID.
3239 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
3240 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003241 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003242 return id;
3243 }
3244
Pengquan Meng70c9885332017-10-02 18:09:03 -07003245 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003246 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003247 mConnectionById.put(callId, connection);
3248 mIdByConnection.put(connection, callId);
3249 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003250 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003251 connection.setPhoneAccountHandle(handle);
3252 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003253 }
3254
Anthony Lee30e65842014-11-06 16:30:53 -08003255 /** {@hide} */
3256 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003257 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003258 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003259 String id = mIdByConnection.get(connection);
3260 if (id != null) {
3261 mConnectionById.remove(id);
3262 mIdByConnection.remove(connection);
3263 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003264 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003265 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003266 }
3267
Santos Cordon823fd3c2014-08-07 18:35:18 -07003268 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003269 String originalId = null;
3270 if (conference.getExtras() != null && conference.getExtras()
3271 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3272 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3273 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3274 conference.getTelecomCallId(),
3275 originalId);
3276 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003277 if (mIdByConference.containsKey(conference)) {
3278 Log.w(this, "Re-adding an existing conference: %s.", conference);
3279 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003280 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3281 // cannot determine a ConnectionService class name to associate with the ID, so use
3282 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003283 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003284 mConferenceById.put(id, conference);
3285 mIdByConference.put(conference, id);
3286 conference.addListener(mConferenceListener);
3287 return id;
3288 }
3289
3290 return null;
3291 }
3292
3293 private void removeConference(Conference conference) {
3294 if (mIdByConference.containsKey(conference)) {
3295 conference.removeListener(mConferenceListener);
3296
3297 String id = mIdByConference.get(conference);
3298 mConferenceById.remove(id);
3299 mIdByConference.remove(conference);
3300 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003301
3302 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003303 }
3304 }
3305
Ihab Awad542e0ea2014-05-16 10:22:16 -07003306 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003307 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003308 return mConnectionById.get(callId);
3309 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003310 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003311 return getNullConnection();
3312 }
3313
3314 static synchronized Connection getNullConnection() {
3315 if (sNullConnection == null) {
3316 sNullConnection = new Connection() {};
3317 }
3318 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003319 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003320
3321 private Conference findConferenceForAction(String conferenceId, String action) {
3322 if (mConferenceById.containsKey(conferenceId)) {
3323 return mConferenceById.get(conferenceId);
3324 }
3325 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3326 return getNullConference();
3327 }
3328
Ihab Awadb8e85c72014-08-23 20:34:57 -07003329 private List<String> createConnectionIdList(List<Connection> connections) {
3330 List<String> ids = new ArrayList<>();
3331 for (Connection c : connections) {
3332 if (mIdByConnection.containsKey(c)) {
3333 ids.add(mIdByConnection.get(c));
3334 }
3335 }
3336 Collections.sort(ids);
3337 return ids;
3338 }
3339
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003340 /**
3341 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003342 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003343 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003344 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003345 * @return List of string conference and call Ids.
3346 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003347 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003348 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003349 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003350 // Only allow Connection and Conference conferenceables.
3351 if (c instanceof Connection) {
3352 Connection connection = (Connection) c;
3353 if (mIdByConnection.containsKey(connection)) {
3354 ids.add(mIdByConnection.get(connection));
3355 }
3356 } else if (c instanceof Conference) {
3357 Conference conference = (Conference) c;
3358 if (mIdByConference.containsKey(conference)) {
3359 ids.add(mIdByConference.get(conference));
3360 }
3361 }
3362 }
3363 Collections.sort(ids);
3364 return ids;
3365 }
3366
Santos Cordon0159ac02014-08-21 14:28:11 -07003367 private Conference getNullConference() {
3368 if (sNullConference == null) {
3369 sNullConference = new Conference(null) {};
3370 }
3371 return sNullConference;
3372 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003373
3374 private void endAllConnections() {
3375 // Unbound from telecomm. We should end all connections and conferences.
3376 for (Connection connection : mIdByConnection.keySet()) {
3377 // only operate on top-level calls. Conference calls will be removed on their own.
3378 if (connection.getConference() == null) {
3379 connection.onDisconnect();
3380 }
3381 }
3382 for (Conference conference : mIdByConference.keySet()) {
3383 conference.onDisconnect();
3384 }
3385 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003386
3387 /**
3388 * Retrieves the next call ID as maintainted by the connection service.
3389 *
3390 * @return The call ID.
3391 */
3392 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003393 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003394 return ++mId;
3395 }
3396 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003397
3398 /**
3399 * Returns this handler, ONLY FOR TESTING.
3400 * @hide
3401 */
3402 @VisibleForTesting
3403 public Handler getHandler() {
3404 return mHandler;
3405 }
Santos Cordon980acb92014-05-31 10:31:19 -07003406}