blob: 966ece3a3ba26ee0b8563654a9afc8e7adb710d9 [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;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070023import android.app.Service;
Santos Cordon52d8a152014-06-17 19:08:45 -070024import android.content.ComponentName;
Santos Cordon5c6fa952014-07-20 17:47:12 -070025import android.content.Intent;
Ihab Awad542e0ea2014-05-16 10:22:16 -070026import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070027import android.os.Bundle;
Santos Cordon52d8a152014-06-17 19:08:45 -070028import android.os.Handler;
29import android.os.IBinder;
30import android.os.Looper;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070031import android.os.Message;
Hall Liub64ac4c2017-02-06 10:49:48 -080032import android.os.ParcelFileDescriptor;
33import android.os.RemoteException;
Brad Ebingerb32d4f82016-10-24 16:40:49 -070034import android.telecom.Logging.Session;
Andrew Lee14185762014-07-25 09:41:56 -070035
Brad Ebinger99f17ce2019-09-11 18:06:51 -070036import com.android.internal.annotations.VisibleForTesting;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070037import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070038import com.android.internal.telecom.IConnectionService;
39import com.android.internal.telecom.IConnectionServiceAdapter;
40import com.android.internal.telecom.RemoteServiceCallback;
Santos Cordon52d8a152014-06-17 19:08:45 -070041
Ihab Awad5d0410f2014-07-30 10:07:40 -070042import java.util.ArrayList;
Santos Cordonb6939982014-06-04 20:20:58 -070043import java.util.Collection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070044import java.util.Collections;
Santos Cordon52d8a152014-06-17 19:08:45 -070045import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070046import java.util.Map;
Santos Cordon823fd3c2014-08-07 18:35:18 -070047import java.util.UUID;
mike dooley95e80702014-09-18 14:07:52 -070048import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070049
50/**
Tyler Gunnf5035432017-01-09 09:43:12 -080051 * An abstract service that should be implemented by any apps which either:
52 * <ol>
53 * <li>Can make phone calls (VoIP or otherwise) and want those calls to be integrated into the
54 * built-in phone app. Referred to as a <b>system managed</b> {@link ConnectionService}.</li>
55 * <li>Are a standalone calling app and don't want their calls to be integrated into the
56 * built-in phone app. Referred to as a <b>self managed</b> {@link ConnectionService}.</li>
57 * </ol>
58 * Once implemented, the {@link ConnectionService} needs to take the following steps so that Telecom
59 * will bind to it:
Santos Cordona663f862014-10-29 13:49:58 -070060 * <p>
61 * 1. <i>Registration in AndroidManifest.xml</i>
62 * <br/>
63 * <pre>
64 * &lt;service android:name="com.example.package.MyConnectionService"
65 * android:label="@string/some_label_for_my_connection_service"
Yorke Lee249c12e2015-05-13 15:59:29 -070066 * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"&gt;
Santos Cordona663f862014-10-29 13:49:58 -070067 * &lt;intent-filter&gt;
68 * &lt;action android:name="android.telecom.ConnectionService" /&gt;
69 * &lt;/intent-filter&gt;
70 * &lt;/service&gt;
71 * </pre>
72 * <p>
73 * 2. <i> Registration of {@link PhoneAccount} with {@link TelecomManager}.</i>
74 * <br/>
75 * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
76 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080077 * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
kopriva82c591b2018-10-08 15:57:00 -070078 * before Telecom will bind to them. Self-managed {@link ConnectionService}s must be granted the
Tyler Gunnf5035432017-01-09 09:43:12 -080079 * appropriate permission before Telecom will bind to them.
80 * <p>
81 * Once registered and enabled by the user in the phone app settings or granted permission, telecom
82 * will bind to a {@link ConnectionService} implementation when it wants that
83 * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
84 * call through {@link TelecomManager#addNewIncomingCall}. The {@link ConnectionService} can then
85 * expect a call to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection}
86 * wherein it should provide a new instance of a {@link Connection} object. It is through this
87 * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
Santos Cordona663f862014-10-29 13:49:58 -070088 * receives call-commands such as answer, reject, hold and disconnect.
89 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080090 * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
Ihab Awad542e0ea2014-05-16 10:22:16 -070091 */
Sailesh Nepal2a46b902014-07-04 17:21:07 -070092public abstract class ConnectionService extends Service {
Santos Cordon5c6fa952014-07-20 17:47:12 -070093 /**
94 * The {@link Intent} that must be declared as handled by the service.
95 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070096 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
Tyler Gunnef9f6f92014-09-12 22:16:17 -070097 public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
Santos Cordon5c6fa952014-07-20 17:47:12 -070098
Tyler Gunn8bf76572017-04-06 15:30:08 -070099 /**
100 * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
101 * being asked to create a new outgoing {@link Connection} is to perform a handover of an
102 * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}. Will
103 * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
104 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
105 * <p>
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700106 * When your {@link ConnectionService} receives this extra, it should communicate the fact that
107 * this is a handover to the other device's matching {@link ConnectionService}. That
Tyler Gunn8bf76572017-04-06 15:30:08 -0700108 * {@link ConnectionService} will continue the handover using
109 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700110 * {@link TelecomManager#EXTRA_IS_HANDOVER}. Telecom will match the phone numbers of the
111 * handover call on the other device with ongoing calls for {@link ConnectionService}s which
112 * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700113 * @hide
114 */
115 public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
116
Ihab Awad542e0ea2014-05-16 10:22:16 -0700117 // Flag controlling whether PII is emitted into the logs
Ihab Awad60ac30b2014-05-20 22:32:12 -0700118 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700119
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700120 // Session Definitions
121 private static final String SESSION_HANDLER = "H.";
122 private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
123 private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
124 private static final String SESSION_CREATE_CONN = "CS.crCo";
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700125 private static final String SESSION_CREATE_CONN_COMPLETE = "CS.crCoC";
Tyler Gunn44e01912017-01-31 10:49:05 -0800126 private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700127 private static final String SESSION_ABORT = "CS.ab";
128 private static final String SESSION_ANSWER = "CS.an";
129 private static final String SESSION_ANSWER_VIDEO = "CS.anV";
Pooja Jaind34698d2017-12-28 14:15:31 +0530130 private static final String SESSION_DEFLECT = "CS.def";
Ravi Palurif4b38e72020-02-05 12:35:41 +0530131 private static final String SESSION_TRANSFER = "CS.trans";
132 private static final String SESSION_CONSULTATIVE_TRANSFER = "CS.cTrans";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700133 private static final String SESSION_REJECT = "CS.r";
134 private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
135 private static final String SESSION_SILENCE = "CS.s";
136 private static final String SESSION_DISCONNECT = "CS.d";
137 private static final String SESSION_HOLD = "CS.h";
138 private static final String SESSION_UNHOLD = "CS.u";
139 private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
Grace Jiae99fde92021-01-19 14:58:01 -0800140 private static final String SESSION_USING_ALTERNATIVE_UI = "CS.uAU";
141 private static final String SESSION_TRACKED_BY_NON_UI_SERVICE = "CS.tBNUS";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700142 private static final String SESSION_PLAY_DTMF = "CS.pDT";
143 private static final String SESSION_STOP_DTMF = "CS.sDT";
144 private static final String SESSION_CONFERENCE = "CS.c";
145 private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
146 private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
147 private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
Ravi Paluri404babb2020-01-23 19:02:44 +0530148 private static final String SESSION_ADD_PARTICIPANT = "CS.aP";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700149 private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
150 private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
151 private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
Hall Liu49cabcc2021-01-15 11:41:48 -0800152 private static final String SESSION_CALL_FILTERING_COMPLETED = "CS.oCFC";
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;
Hall Liu49cabcc2021-01-15 11:41:48 -0800206 private static final int MSG_ON_CALL_FILTERING_COMPLETED = 42;
Grace Jiae99fde92021-01-19 14:58:01 -0800207 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 Jiae99fde92021-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
Hall Liu49cabcc2021-01-15 11:41:48 -0800761 public void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts,
Hall Liu5efe9972021-02-04 13:09:45 -0800762 CallScreeningService.ParcelableCallResponse callScreeningResponse,
763 boolean isResponseFromSystemDialer,
Hall Liu49cabcc2021-01-15 11:41:48 -0800764 Session.Info sessionInfo) {
765 Log.startSession(sessionInfo, SESSION_CALL_FILTERING_COMPLETED);
766 try {
767 SomeArgs args = SomeArgs.obtain();
768 args.arg1 = callId;
769 args.arg2 = isBlocked;
770 args.arg3 = isInContacts;
Hall Liu5efe9972021-02-04 13:09:45 -0800771 args.arg4 = callScreeningResponse;
772 args.arg5 = isResponseFromSystemDialer;
773 args.arg6 = Log.createSubsession();
Hall Liu49cabcc2021-01-15 11:41:48 -0800774 mHandler.obtainMessage(MSG_ON_CALL_FILTERING_COMPLETED, args).sendToTarget();
775 } finally {
776 Log.endSession();
777 }
778 }
779
780 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700781 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
782 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
783 try {
784 SomeArgs args = SomeArgs.obtain();
785 args.arg1 = callId;
786 args.arg2 = extras;
787 args.arg3 = Log.createSubsession();
788 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
789 } finally {
790 Log.endSession();
791 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700792 }
Hall Liub64ac4c2017-02-06 10:49:48 -0800793
794 @Override
795 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
796 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
797 Log.startSession(sessionInfo, SESSION_START_RTT);
798 try {
799 SomeArgs args = SomeArgs.obtain();
800 args.arg1 = callId;
801 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
802 args.arg3 = Log.createSubsession();
803 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
804 } finally {
805 Log.endSession();
806 }
807 }
808
809 @Override
810 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
811 Log.startSession(sessionInfo, SESSION_STOP_RTT);
812 try {
813 SomeArgs args = SomeArgs.obtain();
814 args.arg1 = callId;
815 args.arg2 = Log.createSubsession();
816 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
817 } finally {
818 Log.endSession();
819 }
820 }
821
822 @Override
823 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
824 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
825 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
826 try {
827 SomeArgs args = SomeArgs.obtain();
828 args.arg1 = callId;
829 if (toInCall == null || fromInCall == null) {
830 args.arg2 = null;
831 } else {
832 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
833 }
834 args.arg3 = Log.createSubsession();
835 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
836 } finally {
837 Log.endSession();
838 }
839 }
Pengquan Meng731c1a32017-11-21 18:01:13 -0800840
841 @Override
842 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
843 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
844 try {
845 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
846 } finally {
847 Log.endSession();
848 }
849 }
850
851 @Override
852 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
853 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
854 try {
855 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
856 } finally {
857 Log.endSession();
858 }
859 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700860 };
861
862 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
863 @Override
864 public void handleMessage(Message msg) {
865 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700866 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
867 SomeArgs args = (SomeArgs) msg.obj;
868 try {
869 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
870 Log.continueSession((Session) args.arg2,
871 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
872 mAdapter.addAdapter(adapter);
873 onAdapterAttached();
874 } finally {
875 args.recycle();
876 Log.endSession();
877 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700878 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700879 }
880 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
881 SomeArgs args = (SomeArgs) msg.obj;
882 try {
883 Log.continueSession((Session) args.arg2,
884 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
885 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
886 } finally {
887 args.recycle();
888 Log.endSession();
889 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700890 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700891 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700892 case MSG_CREATE_CONNECTION: {
893 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700894 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -0700895 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700896 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -0700897 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700898 final String id = (String) args.arg2;
899 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700900 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -0700901 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700902 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700903 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700904 mPreInitializationConnectionRequests.add(
905 new android.telecom.Logging.Runnable(
906 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
907 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700908 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700909 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700910 createConnection(
911 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700912 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700913 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700914 isIncoming,
915 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700916 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700917 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -0700918 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700919 createConnection(
920 connectionManagerPhoneAccount,
921 id,
922 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700923 isIncoming,
924 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700925 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700926 } finally {
927 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700928 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -0700929 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700930 break;
Ihab Awadf8b69882014-07-25 15:14:01 -0700931 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700932 case MSG_CREATE_CONNECTION_COMPLETE: {
933 SomeArgs args = (SomeArgs) msg.obj;
934 Log.continueSession((Session) args.arg2,
935 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
936 try {
937 final String id = (String) args.arg1;
938 if (!mAreAccountsInitialized) {
939 Log.d(this, "Enqueueing pre-init request %s", id);
940 mPreInitializationConnectionRequests.add(
941 new android.telecom.Logging.Runnable(
942 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
943 + ".pICR",
944 null /*lock*/) {
945 @Override
946 public void loggedRun() {
947 notifyCreateConnectionComplete(id);
948 }
949 }.prepare());
950 } else {
951 notifyCreateConnectionComplete(id);
952 }
953 } finally {
954 args.recycle();
955 Log.endSession();
956 }
957 break;
958 }
Tyler Gunn44e01912017-01-31 10:49:05 -0800959 case MSG_CREATE_CONNECTION_FAILED: {
960 SomeArgs args = (SomeArgs) msg.obj;
961 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
962 SESSION_CREATE_CONN_FAILED);
963 try {
964 final String id = (String) args.arg1;
965 final ConnectionRequest request = (ConnectionRequest) args.arg2;
966 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800967 final PhoneAccountHandle connectionMgrPhoneAccount =
968 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -0800969 if (!mAreAccountsInitialized) {
970 Log.d(this, "Enqueueing pre-init request %s", id);
971 mPreInitializationConnectionRequests.add(
972 new android.telecom.Logging.Runnable(
973 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
974 null /*lock*/) {
975 @Override
976 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800977 createConnectionFailed(connectionMgrPhoneAccount, id,
978 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800979 }
980 }.prepare());
981 } else {
982 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -0800983 createConnectionFailed(connectionMgrPhoneAccount, id, request,
984 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800985 }
986 } finally {
987 args.recycle();
988 Log.endSession();
989 }
990 break;
991 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530992 case MSG_CREATE_CONFERENCE: {
993 SomeArgs args = (SomeArgs) msg.obj;
994 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
995 try {
996 final PhoneAccountHandle connectionManagerPhoneAccount =
997 (PhoneAccountHandle) args.arg1;
998 final String id = (String) args.arg2;
999 final ConnectionRequest request = (ConnectionRequest) args.arg3;
1000 final boolean isIncoming = args.argi1 == 1;
1001 final boolean isUnknown = args.argi2 == 1;
1002 if (!mAreAccountsInitialized) {
1003 Log.d(this, "Enqueueing pre-initconference request %s", id);
1004 mPreInitializationConnectionRequests.add(
1005 new android.telecom.Logging.Runnable(
1006 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
1007 null /*lock*/) {
1008 @Override
1009 public void loggedRun() {
1010 createConference(connectionManagerPhoneAccount,
1011 id,
1012 request,
1013 isIncoming,
1014 isUnknown);
1015 }
1016 }.prepare());
1017 } else {
1018 createConference(connectionManagerPhoneAccount,
1019 id,
1020 request,
1021 isIncoming,
1022 isUnknown);
1023 }
1024 } finally {
1025 args.recycle();
1026 Log.endSession();
1027 }
1028 break;
1029 }
1030 case MSG_CREATE_CONFERENCE_COMPLETE: {
1031 SomeArgs args = (SomeArgs) msg.obj;
1032 Log.continueSession((Session) args.arg2,
1033 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1034 try {
1035 final String id = (String) args.arg1;
1036 if (!mAreAccountsInitialized) {
1037 Log.d(this, "Enqueueing pre-init conference request %s", id);
1038 mPreInitializationConnectionRequests.add(
1039 new android.telecom.Logging.Runnable(
1040 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
1041 + ".pIConfR",
1042 null /*lock*/) {
1043 @Override
1044 public void loggedRun() {
1045 notifyCreateConferenceComplete(id);
1046 }
1047 }.prepare());
1048 } else {
1049 notifyCreateConferenceComplete(id);
1050 }
1051 } finally {
1052 args.recycle();
1053 Log.endSession();
1054 }
1055 break;
1056 }
1057 case MSG_CREATE_CONFERENCE_FAILED: {
1058 SomeArgs args = (SomeArgs) msg.obj;
1059 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1060 SESSION_CREATE_CONN_FAILED);
1061 try {
1062 final String id = (String) args.arg1;
1063 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1064 final boolean isIncoming = args.argi1 == 1;
1065 final PhoneAccountHandle connectionMgrPhoneAccount =
1066 (PhoneAccountHandle) args.arg4;
1067 if (!mAreAccountsInitialized) {
1068 Log.d(this, "Enqueueing pre-init conference request %s", id);
1069 mPreInitializationConnectionRequests.add(
1070 new android.telecom.Logging.Runnable(
1071 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
1072 + ".pIConfR",
1073 null /*lock*/) {
1074 @Override
1075 public void loggedRun() {
1076 createConferenceFailed(connectionMgrPhoneAccount, id,
1077 request, isIncoming);
1078 }
1079 }.prepare());
1080 } else {
1081 Log.i(this, "createConferenceFailed %s", id);
1082 createConferenceFailed(connectionMgrPhoneAccount, id, request,
1083 isIncoming);
1084 }
1085 } finally {
1086 args.recycle();
1087 Log.endSession();
1088 }
1089 break;
1090 }
1091
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001092 case MSG_HANDOVER_FAILED: {
1093 SomeArgs args = (SomeArgs) msg.obj;
1094 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1095 SESSION_HANDOVER_FAILED);
1096 try {
1097 final String id = (String) args.arg1;
1098 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1099 final int reason = (int) args.arg4;
1100 if (!mAreAccountsInitialized) {
1101 Log.d(this, "Enqueueing pre-init request %s", id);
1102 mPreInitializationConnectionRequests.add(
1103 new android.telecom.Logging.Runnable(
1104 SESSION_HANDLER
1105 + SESSION_HANDOVER_FAILED + ".pICR",
1106 null /*lock*/) {
1107 @Override
1108 public void loggedRun() {
1109 handoverFailed(id, request, reason);
1110 }
1111 }.prepare());
1112 } else {
1113 Log.i(this, "createConnectionFailed %s", id);
1114 handoverFailed(id, request, reason);
1115 }
1116 } finally {
1117 args.recycle();
1118 Log.endSession();
1119 }
1120 break;
1121 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001122 case MSG_ABORT: {
1123 SomeArgs args = (SomeArgs) msg.obj;
1124 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1125 try {
1126 abort((String) args.arg1);
1127 } finally {
1128 args.recycle();
1129 Log.endSession();
1130 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001131 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001132 }
1133 case MSG_ANSWER: {
1134 SomeArgs args = (SomeArgs) msg.obj;
1135 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1136 try {
1137 answer((String) args.arg1);
1138 } finally {
1139 args.recycle();
1140 Log.endSession();
1141 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001142 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001143 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001144 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001145 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001146 Log.continueSession((Session) args.arg2,
1147 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001148 try {
1149 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001150 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001151 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001152 } finally {
1153 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001154 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001155 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001156 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001157 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301158 case MSG_DEFLECT: {
1159 SomeArgs args = (SomeArgs) msg.obj;
1160 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1161 try {
1162 deflect((String) args.arg1, (Uri) args.arg2);
1163 } finally {
1164 args.recycle();
1165 Log.endSession();
1166 }
1167 break;
1168 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001169 case MSG_REJECT: {
1170 SomeArgs args = (SomeArgs) msg.obj;
1171 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1172 try {
1173 reject((String) args.arg1);
1174 } finally {
1175 args.recycle();
1176 Log.endSession();
1177 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001178 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001179 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001180 case MSG_REJECT_WITH_REASON: {
1181 SomeArgs args = (SomeArgs) msg.obj;
1182 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1183 try {
1184 reject((String) args.arg1, args.argi1);
1185 } finally {
1186 args.recycle();
1187 Log.endSession();
1188 }
1189 break;
1190 }
Bryce Lee81901682015-08-28 16:38:02 -07001191 case MSG_REJECT_WITH_MESSAGE: {
1192 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001193 Log.continueSession((Session) args.arg3,
1194 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001195 try {
1196 reject((String) args.arg1, (String) args.arg2);
1197 } finally {
1198 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001199 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001200 }
1201 break;
1202 }
Ravi Palurif4b38e72020-02-05 12:35:41 +05301203 case MSG_EXPLICIT_CALL_TRANSFER: {
1204 SomeArgs args = (SomeArgs) msg.obj;
1205 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_TRANSFER);
1206 try {
1207 final boolean isConfirmationRequired = args.argi1 == 1;
1208 transfer((String) args.arg1, (Uri) args.arg2, isConfirmationRequired);
1209 } finally {
1210 args.recycle();
1211 Log.endSession();
1212 }
1213 break;
1214 }
1215 case MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE: {
1216 SomeArgs args = (SomeArgs) msg.obj;
1217 Log.continueSession(
1218 (Session) args.arg3, SESSION_HANDLER + SESSION_CONSULTATIVE_TRANSFER);
1219 try {
1220 consultativeTransfer((String) args.arg1, (String) args.arg2);
1221 } finally {
1222 args.recycle();
1223 Log.endSession();
1224 }
1225 break;
1226 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001227 case MSG_DISCONNECT: {
1228 SomeArgs args = (SomeArgs) msg.obj;
1229 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1230 try {
1231 disconnect((String) args.arg1);
1232 } finally {
1233 args.recycle();
1234 Log.endSession();
1235 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001236 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001237 }
1238 case MSG_SILENCE: {
1239 SomeArgs args = (SomeArgs) msg.obj;
1240 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1241 try {
1242 silence((String) args.arg1);
1243 } finally {
1244 args.recycle();
1245 Log.endSession();
1246 }
Bryce Leecac50772015-11-17 15:13:29 -08001247 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001248 }
1249 case MSG_HOLD: {
1250 SomeArgs args = (SomeArgs) msg.obj;
1251 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1252 try {
1253 hold((String) args.arg1);
1254 } finally {
1255 args.recycle();
1256 Log.endSession();
1257 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001258 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001259 }
1260 case MSG_UNHOLD: {
1261 SomeArgs args = (SomeArgs) msg.obj;
1262 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1263 try {
1264 unhold((String) args.arg1);
1265 } finally {
1266 args.recycle();
1267 Log.endSession();
1268 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001269 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001270 }
Yorke Lee4af59352015-05-13 14:14:54 -07001271 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001272 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001273 Log.continueSession((Session) args.arg3,
1274 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001275 try {
1276 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001277 CallAudioState audioState = (CallAudioState) args.arg2;
1278 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001279 } finally {
1280 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001281 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001282 }
1283 break;
1284 }
Grace Jiae99fde92021-01-19 14:58:01 -08001285 case MSG_ON_USING_ALTERNATIVE_UI: {
1286 SomeArgs args = (SomeArgs) msg.obj;
1287 Log.continueSession((Session) args.arg3,
1288 SESSION_HANDLER + SESSION_USING_ALTERNATIVE_UI);
1289 try {
1290 String callId = (String) args.arg1;
1291 boolean isUsingAlternativeUi = (boolean) args.arg2;
1292 onUsingAlternativeUi(callId, isUsingAlternativeUi);
1293 } finally {
1294 args.recycle();
1295 Log.endSession();
1296 }
1297 break;
1298 }
1299 case MSG_ON_TRACKED_BY_NON_UI_SERVICE: {
1300 SomeArgs args = (SomeArgs) msg.obj;
1301 Log.continueSession((Session) args.arg3,
1302 SESSION_HANDLER + SESSION_TRACKED_BY_NON_UI_SERVICE);
1303 try {
1304 String callId = (String) args.arg1;
1305 boolean isTracked = (boolean) args.arg2;
1306 onTrackedByNonUiService(callId, isTracked);
1307 } finally {
1308 args.recycle();
1309 Log.endSession();
1310 }
1311 break;
1312 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001313 case MSG_PLAY_DTMF_TONE: {
1314 SomeArgs args = (SomeArgs) msg.obj;
1315 try {
1316 Log.continueSession((Session) args.arg3,
1317 SESSION_HANDLER + SESSION_PLAY_DTMF);
1318 playDtmfTone((String) args.arg2, (char) args.arg1);
1319 } finally {
1320 args.recycle();
1321 Log.endSession();
1322 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001323 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001324 }
1325 case MSG_STOP_DTMF_TONE: {
1326 SomeArgs args = (SomeArgs) msg.obj;
1327 try {
1328 Log.continueSession((Session) args.arg2,
1329 SESSION_HANDLER + SESSION_STOP_DTMF);
1330 stopDtmfTone((String) args.arg1);
1331 } finally {
1332 args.recycle();
1333 Log.endSession();
1334 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001335 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001336 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001337 case MSG_CONFERENCE: {
1338 SomeArgs args = (SomeArgs) msg.obj;
1339 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001340 Log.continueSession((Session) args.arg3,
1341 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001342 String callId1 = (String) args.arg1;
1343 String callId2 = (String) args.arg2;
1344 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001345 } finally {
1346 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001347 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001348 }
1349 break;
1350 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001351 case MSG_SPLIT_FROM_CONFERENCE: {
1352 SomeArgs args = (SomeArgs) msg.obj;
1353 try {
1354 Log.continueSession((Session) args.arg2,
1355 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1356 splitFromConference((String) args.arg1);
1357 } finally {
1358 args.recycle();
1359 Log.endSession();
1360 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001361 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001362 }
1363 case MSG_MERGE_CONFERENCE: {
1364 SomeArgs args = (SomeArgs) msg.obj;
1365 try {
1366 Log.continueSession((Session) args.arg2,
1367 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1368 mergeConference((String) args.arg1);
1369 } finally {
1370 args.recycle();
1371 Log.endSession();
1372 }
Santos Cordona4868042014-09-04 17:39:22 -07001373 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001374 }
1375 case MSG_SWAP_CONFERENCE: {
1376 SomeArgs args = (SomeArgs) msg.obj;
1377 try {
1378 Log.continueSession((Session) args.arg2,
1379 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1380 swapConference((String) args.arg1);
1381 } finally {
1382 args.recycle();
1383 Log.endSession();
1384 }
Santos Cordona4868042014-09-04 17:39:22 -07001385 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001386 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301387 case MSG_ADD_PARTICIPANT: {
1388 SomeArgs args = (SomeArgs) msg.obj;
1389 try {
1390 Log.continueSession((Session) args.arg3,
1391 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1392 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1393 } finally {
1394 args.recycle();
1395 Log.endSession();
1396 }
1397 break;
1398 }
1399
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001400 case MSG_ON_POST_DIAL_CONTINUE: {
1401 SomeArgs args = (SomeArgs) msg.obj;
1402 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001403 Log.continueSession((Session) args.arg2,
1404 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001405 String callId = (String) args.arg1;
1406 boolean proceed = (args.argi1 == 1);
1407 onPostDialContinue(callId, proceed);
1408 } finally {
1409 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001410 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001411 }
1412 break;
1413 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001414 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001415 SomeArgs args = (SomeArgs) msg.obj;
1416 try {
1417 Log.continueSession((Session) args.arg2,
1418 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1419 pullExternalCall((String) args.arg1);
1420 } finally {
1421 args.recycle();
1422 Log.endSession();
1423 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001424 break;
1425 }
1426 case MSG_SEND_CALL_EVENT: {
1427 SomeArgs args = (SomeArgs) msg.obj;
1428 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001429 Log.continueSession((Session) args.arg4,
1430 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001431 String callId = (String) args.arg1;
1432 String event = (String) args.arg2;
1433 Bundle extras = (Bundle) args.arg3;
1434 sendCallEvent(callId, event, extras);
1435 } finally {
1436 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001437 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001438 }
1439 break;
1440 }
Hall Liu49cabcc2021-01-15 11:41:48 -08001441 case MSG_ON_CALL_FILTERING_COMPLETED: {
1442 SomeArgs args = (SomeArgs) msg.obj;
1443 try {
Hall Liu5efe9972021-02-04 13:09:45 -08001444 Log.continueSession((Session) args.arg6,
Hall Liu49cabcc2021-01-15 11:41:48 -08001445 SESSION_HANDLER + SESSION_CALL_FILTERING_COMPLETED);
1446 String callId = (String) args.arg1;
1447 boolean isBlocked = (boolean) args.arg2;
1448 boolean isInContacts = (boolean) args.arg3;
Hall Liu5efe9972021-02-04 13:09:45 -08001449 CallScreeningService.ParcelableCallResponse callScreeningResponse =
1450 (CallScreeningService.ParcelableCallResponse) args.arg4;
1451 boolean isResponseFromSystemDialer = (boolean) args.arg5;
1452 onCallFilteringCompleted(callId, isBlocked, isInContacts,
1453 callScreeningResponse, isResponseFromSystemDialer);
Hall Liu49cabcc2021-01-15 11:41:48 -08001454 } finally {
1455 args.recycle();
1456 Log.endSession();
1457 }
1458 break;
1459 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001460 case MSG_HANDOVER_COMPLETE: {
1461 SomeArgs args = (SomeArgs) msg.obj;
1462 try {
1463 Log.continueSession((Session) args.arg2,
1464 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1465 String callId = (String) args.arg1;
1466 notifyHandoverComplete(callId);
1467 } finally {
1468 args.recycle();
1469 Log.endSession();
1470 }
1471 break;
1472 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001473 case MSG_ON_EXTRAS_CHANGED: {
1474 SomeArgs args = (SomeArgs) msg.obj;
1475 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001476 Log.continueSession((Session) args.arg3,
1477 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001478 String callId = (String) args.arg1;
1479 Bundle extras = (Bundle) args.arg2;
1480 handleExtrasChanged(callId, extras);
1481 } finally {
1482 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001483 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001484 }
1485 break;
1486 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001487 case MSG_ON_START_RTT: {
1488 SomeArgs args = (SomeArgs) msg.obj;
1489 try {
1490 Log.continueSession((Session) args.arg3,
1491 SESSION_HANDLER + SESSION_START_RTT);
1492 String callId = (String) args.arg1;
1493 Connection.RttTextStream rttTextStream =
1494 (Connection.RttTextStream) args.arg2;
1495 startRtt(callId, rttTextStream);
1496 } finally {
1497 args.recycle();
1498 Log.endSession();
1499 }
1500 break;
1501 }
1502 case MSG_ON_STOP_RTT: {
1503 SomeArgs args = (SomeArgs) msg.obj;
1504 try {
1505 Log.continueSession((Session) args.arg2,
1506 SESSION_HANDLER + SESSION_STOP_RTT);
1507 String callId = (String) args.arg1;
1508 stopRtt(callId);
1509 } finally {
1510 args.recycle();
1511 Log.endSession();
1512 }
1513 break;
1514 }
1515 case MSG_RTT_UPGRADE_RESPONSE: {
1516 SomeArgs args = (SomeArgs) msg.obj;
1517 try {
1518 Log.continueSession((Session) args.arg3,
1519 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1520 String callId = (String) args.arg1;
1521 Connection.RttTextStream rttTextStream =
1522 (Connection.RttTextStream) args.arg2;
1523 handleRttUpgradeResponse(callId, rttTextStream);
1524 } finally {
1525 args.recycle();
1526 Log.endSession();
1527 }
1528 break;
1529 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001530 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1531 onConnectionServiceFocusGained();
1532 break;
1533 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1534 onConnectionServiceFocusLost();
1535 break;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001536 default:
1537 break;
1538 }
1539 }
1540 };
1541
Santos Cordon823fd3c2014-08-07 18:35:18 -07001542 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1543 @Override
1544 public void onStateChanged(Conference conference, int oldState, int newState) {
1545 String id = mIdByConference.get(conference);
1546 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301547 case Connection.STATE_RINGING:
1548 mAdapter.setRinging(id);
1549 break;
1550 case Connection.STATE_DIALING:
1551 mAdapter.setDialing(id);
1552 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001553 case Connection.STATE_ACTIVE:
1554 mAdapter.setActive(id);
1555 break;
1556 case Connection.STATE_HOLDING:
1557 mAdapter.setOnHold(id);
1558 break;
1559 case Connection.STATE_DISCONNECTED:
1560 // handled by onDisconnected
1561 break;
1562 }
1563 }
1564
1565 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001566 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001567 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001568 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001569 }
1570
1571 @Override
1572 public void onConnectionAdded(Conference conference, Connection connection) {
1573 }
1574
1575 @Override
1576 public void onConnectionRemoved(Conference conference, Connection connection) {
1577 }
1578
1579 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001580 public void onConferenceableConnectionsChanged(
1581 Conference conference, List<Connection> conferenceableConnections) {
1582 mAdapter.setConferenceableConnections(
1583 mIdByConference.get(conference),
1584 createConnectionIdList(conferenceableConnections));
1585 }
1586
1587 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001588 public void onDestroyed(Conference conference) {
1589 removeConference(conference);
1590 }
1591
1592 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001593 public void onConnectionCapabilitiesChanged(
1594 Conference conference,
1595 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001596 String id = mIdByConference.get(conference);
1597 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001598 Connection.capabilitiesToString(connectionCapabilities));
1599 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001600 }
Rekha Kumar07366812015-03-24 16:42:31 -07001601
1602 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001603 public void onConnectionPropertiesChanged(
1604 Conference conference,
1605 int connectionProperties) {
1606 String id = mIdByConference.get(conference);
1607 Log.d(this, "call capabilities: conference: %s",
1608 Connection.propertiesToString(connectionProperties));
1609 mAdapter.setConnectionProperties(id, connectionProperties);
1610 }
1611
1612 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001613 public void onVideoStateChanged(Conference c, int videoState) {
1614 String id = mIdByConference.get(c);
1615 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1616 mAdapter.setVideoState(id, videoState);
1617 }
1618
1619 @Override
1620 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1621 String id = mIdByConference.get(c);
1622 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1623 videoProvider);
1624 mAdapter.setVideoProvider(id, videoProvider);
1625 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001626
1627 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001628 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1629 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001630 if (id != null) {
1631 mAdapter.setStatusHints(id, statusHints);
1632 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001633 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001634
1635 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001636 public void onExtrasChanged(Conference c, Bundle extras) {
1637 String id = mIdByConference.get(c);
1638 if (id != null) {
1639 mAdapter.putExtras(id, extras);
1640 }
1641 }
1642
1643 @Override
1644 public void onExtrasRemoved(Conference c, List<String> keys) {
1645 String id = mIdByConference.get(c);
1646 if (id != null) {
1647 mAdapter.removeExtras(id, keys);
1648 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001649 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001650
1651 @Override
1652 public void onConferenceStateChanged(Conference c, boolean isConference) {
1653 String id = mIdByConference.get(c);
1654 if (id != null) {
1655 mAdapter.setConferenceState(id, isConference);
1656 }
1657 }
1658
1659 @Override
Brad Ebingere0c12f42020-04-08 16:25:12 -07001660 public void onCallDirectionChanged(Conference c, int direction) {
1661 String id = mIdByConference.get(c);
1662 if (id != null) {
1663 mAdapter.setCallDirection(id, direction);
1664 }
1665 }
1666
1667 @Override
Tyler Gunn68a73a42018-10-03 15:38:57 -07001668 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1669 String id = mIdByConference.get(c);
1670 if (id != null) {
1671 mAdapter.setAddress(id, newAddress, presentation);
1672 }
1673 }
1674
1675 @Override
1676 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1677 int presentation) {
1678 String id = mIdByConference.get(c);
1679 if (id != null) {
1680 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1681 }
1682 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001683
1684 @Override
1685 public void onConnectionEvent(Conference c, String event, Bundle extras) {
1686 String id = mIdByConference.get(c);
1687 if (id != null) {
1688 mAdapter.onConnectionEvent(id, event, extras);
1689 }
1690 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301691
1692 @Override
1693 public void onRingbackRequested(Conference c, boolean ringback) {
1694 String id = mIdByConference.get(c);
1695 Log.d(this, "Adapter conference onRingback %b", ringback);
1696 mAdapter.setRingbackRequested(id, ringback);
1697 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001698 };
1699
Ihab Awad542e0ea2014-05-16 10:22:16 -07001700 private final Connection.Listener mConnectionListener = new Connection.Listener() {
1701 @Override
1702 public void onStateChanged(Connection c, int state) {
1703 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07001704 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001705 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001706 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001707 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001708 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001709 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001710 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001711 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001712 case Connection.STATE_PULLING_CALL:
1713 mAdapter.setPulling(id);
1714 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001715 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001716 // Handled in onDisconnected()
1717 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001718 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001719 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001720 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001721 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001722 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07001723 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001724 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001725 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001726 break;
1727 }
1728 }
1729
1730 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001731 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07001732 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07001733 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001734 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001735 }
1736
1737 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07001738 public void onVideoStateChanged(Connection c, int videoState) {
1739 String id = mIdByConnection.get(c);
1740 Log.d(this, "Adapter set video state %d", videoState);
1741 mAdapter.setVideoState(id, videoState);
1742 }
1743
1744 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001745 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001746 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001747 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07001748 }
1749
1750 @Override
1751 public void onCallerDisplayNameChanged(
1752 Connection c, String callerDisplayName, int presentation) {
1753 String id = mIdByConnection.get(c);
1754 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001755 }
1756
1757 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07001758 public void onDestroyed(Connection c) {
1759 removeConnection(c);
1760 }
Ihab Awadf8358972014-05-28 16:46:42 -07001761
1762 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001763 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07001764 String id = mIdByConnection.get(c);
1765 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001766 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001767 }
1768
1769 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001770 public void onPostDialChar(Connection c, char nextChar) {
1771 String id = mIdByConnection.get(c);
1772 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
1773 mAdapter.onPostDialChar(id, nextChar);
1774 }
1775
1776 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001777 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07001778 String id = mIdByConnection.get(c);
1779 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07001780 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07001781 }
Santos Cordonb6939982014-06-04 20:20:58 -07001782
1783 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001784 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07001785 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001786 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001787 Connection.capabilitiesToString(capabilities));
1788 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07001789 }
1790
Santos Cordonb6939982014-06-04 20:20:58 -07001791 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001792 public void onConnectionPropertiesChanged(Connection c, int properties) {
1793 String id = mIdByConnection.get(c);
1794 Log.d(this, "properties: parcelableconnection: %s",
1795 Connection.propertiesToString(properties));
1796 mAdapter.setConnectionProperties(id, properties);
1797 }
1798
1799 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001800 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001801 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07001802 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1803 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001804 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001805 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001806
1807 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001808 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001809 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001810 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001811 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001812
1813 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001814 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001815 String id = mIdByConnection.get(c);
1816 mAdapter.setStatusHints(id, statusHints);
1817 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001818
1819 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001820 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001821 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001822 mAdapter.setConferenceableConnections(
1823 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001824 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001825 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001826
1827 @Override
1828 public void onConferenceChanged(Connection connection, Conference conference) {
1829 String id = mIdByConnection.get(connection);
1830 if (id != null) {
1831 String conferenceId = null;
1832 if (conference != null) {
1833 conferenceId = mIdByConference.get(conference);
1834 }
1835 mAdapter.setIsConferenced(id, conferenceId);
1836 }
1837 }
Anthony Lee17455a32015-04-24 15:25:29 -07001838
1839 @Override
1840 public void onConferenceMergeFailed(Connection connection) {
1841 String id = mIdByConnection.get(connection);
1842 if (id != null) {
1843 mAdapter.onConferenceMergeFailed(id);
1844 }
1845 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001846
1847 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001848 public void onExtrasChanged(Connection c, Bundle extras) {
1849 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001850 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07001851 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001852 }
1853 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001854
Tyler Gunnf5035432017-01-09 09:43:12 -08001855 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001856 public void onExtrasRemoved(Connection c, List<String> keys) {
1857 String id = mIdByConnection.get(c);
1858 if (id != null) {
1859 mAdapter.removeExtras(id, keys);
1860 }
1861 }
1862
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001863 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001864 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001865 String id = mIdByConnection.get(connection);
1866 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001867 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001868 }
1869 }
Tyler Gunnf5035432017-01-09 09:43:12 -08001870
1871 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08001872 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001873 String id = mIdByConnection.get(c);
1874 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08001875 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08001876 }
1877 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001878
1879 @Override
1880 public void onRttInitiationSuccess(Connection c) {
1881 String id = mIdByConnection.get(c);
1882 if (id != null) {
1883 mAdapter.onRttInitiationSuccess(id);
1884 }
1885 }
1886
1887 @Override
1888 public void onRttInitiationFailure(Connection c, int reason) {
1889 String id = mIdByConnection.get(c);
1890 if (id != null) {
1891 mAdapter.onRttInitiationFailure(id, reason);
1892 }
1893 }
1894
1895 @Override
1896 public void onRttSessionRemotelyTerminated(Connection c) {
1897 String id = mIdByConnection.get(c);
1898 if (id != null) {
1899 mAdapter.onRttSessionRemotelyTerminated(id);
1900 }
1901 }
1902
1903 @Override
1904 public void onRemoteRttRequest(Connection c) {
1905 String id = mIdByConnection.get(c);
1906 if (id != null) {
1907 mAdapter.onRemoteRttRequest(id);
1908 }
1909 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05301910
1911 @Override
1912 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
1913 String id = mIdByConnection.get(c);
1914 if (id != null) {
1915 mAdapter.onPhoneAccountChanged(id, pHandle);
1916 }
1917 }
Mengjun Leng25707742017-07-04 11:10:37 +08001918
1919 public void onConnectionTimeReset(Connection c) {
1920 String id = mIdByConnection.get(c);
1921 if (id != null) {
1922 mAdapter.resetConnectionTime(id);
1923 }
1924 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001925 };
1926
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001927 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07001928 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001929 public final IBinder onBind(Intent intent) {
1930 return mBinder;
1931 }
1932
Santos Cordon29f2f2e2014-09-11 19:50:24 -07001933 /** {@inheritDoc} */
1934 @Override
1935 public boolean onUnbind(Intent intent) {
1936 endAllConnections();
1937 return super.onUnbind(intent);
1938 }
1939
Ravi Paluri80aa2142019-12-02 11:57:37 +05301940
1941 /**
1942 * This can be used by telecom to either create a new outgoing conference call or attach
1943 * to an existing incoming conference call. In either case, telecom will cycle through a
1944 * set of services and call createConference until a connection service cancels the process
1945 * or completes it successfully.
1946 */
1947 private void createConference(
1948 final PhoneAccountHandle callManagerAccount,
1949 final String callId,
1950 final ConnectionRequest request,
1951 boolean isIncoming,
1952 boolean isUnknown) {
1953
1954 Conference conference = null;
1955 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
1956 : onCreateOutgoingConference(callManagerAccount, request);
1957
1958 Log.d(this, "createConference, conference: %s", conference);
1959 if (conference == null) {
1960 Log.i(this, "createConference, implementation returned null conference.");
1961 conference = Conference.createFailedConference(
1962 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
1963 request.getAccountHandle());
1964 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001965
1966 Bundle extras = request.getExtras();
1967 Bundle newExtras = new Bundle();
1968 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
1969 if (extras != null) {
1970 // If the request originated from a remote connection service, we will add some
1971 // tracking information that Telecom can use to keep informed of which package
1972 // made the remote request, and which remote connection service was used.
1973 if (extras.containsKey(Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
1974 newExtras.putString(
1975 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
1976 extras.getString(
1977 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME));
1978 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
1979 request.getAccountHandle());
1980 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301981 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001982 conference.putExtras(newExtras);
1983
Ravi Paluri80aa2142019-12-02 11:57:37 +05301984 mConferenceById.put(callId, conference);
1985 mIdByConference.put(conference, callId);
Tyler Gunn460360d2020-07-29 10:21:45 -07001986
Ravi Paluri80aa2142019-12-02 11:57:37 +05301987 conference.addListener(mConferenceListener);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07001988 ParcelableConference parcelableConference = new ParcelableConference.Builder(
1989 request.getAccountHandle(), conference.getState())
1990 .setConnectionCapabilities(conference.getConnectionCapabilities())
1991 .setConnectionProperties(conference.getConnectionProperties())
1992 .setVideoAttributes(conference.getVideoProvider() == null
1993 ? null : conference.getVideoProvider().getInterface(),
1994 conference.getVideoState())
1995 .setConnectTimeMillis(conference.getConnectTimeMillis(),
1996 conference.getConnectionStartElapsedRealtimeMillis())
1997 .setStatusHints(conference.getStatusHints())
1998 .setExtras(conference.getExtras())
1999 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2000 .setCallerDisplayName(conference.getCallerDisplayName(),
2001 conference.getCallerDisplayNamePresentation())
2002 .setDisconnectCause(conference.getDisconnectCause())
2003 .setRingbackRequested(conference.isRingbackRequested())
2004 .build();
Ravi Paluri80aa2142019-12-02 11:57:37 +05302005 if (conference.getState() != Connection.STATE_DISCONNECTED) {
2006 conference.setTelecomCallId(callId);
2007 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
2008 mAdapter.setVideoState(callId, conference.getVideoState());
2009 onConferenceAdded(conference);
2010 }
2011
2012 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
2013 mAdapter.handleCreateConferenceComplete(
2014 callId,
2015 request,
2016 parcelableConference);
2017 }
2018
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002019 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002020 * This can be used by telecom to either create a new outgoing call or attach to an existing
2021 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002022 * createConnection util a connection service cancels the process or completes it successfully.
2023 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002024 private void createConnection(
2025 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002026 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07002027 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07002028 boolean isIncoming,
2029 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002030 boolean isLegacyHandover = request.getExtras() != null &&
2031 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
2032 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
2033 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Grace Jiae99fde92021-01-19 14:58:01 -08002034 boolean addSelfManaged = request.getExtras() != null && request.getExtras().getBoolean(
Grace Jia8b22bb42021-02-02 15:37:32 -08002035 PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
Grace Jiae99fde92021-01-19 14:58:01 -08002036 Log.i(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, "
2037 + "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b, "
2038 + " addSelfManaged: %b", callManagerAccount, callId, request, isIncoming,
2039 isUnknown, isLegacyHandover, isHandover, addSelfManaged);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002040
Sanket Padawee29a2662017-12-01 13:59:27 -08002041 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002042 if (isHandover) {
2043 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
2044 ? (PhoneAccountHandle) request.getExtras().getParcelable(
2045 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08002046 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002047 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002048 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002049 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002050 }
2051 } else {
2052 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
2053 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
2054 : onCreateOutgoingConnection(callManagerAccount, request);
2055 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002056 Log.d(this, "createConnection, connection: %s", connection);
2057 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002058 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002059 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002060 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002061 } else {
2062 try {
2063 Bundle extras = request.getExtras();
2064 if (extras != null) {
2065 // If the request originated from a remote connection service, we will add some
2066 // tracking information that Telecom can use to keep informed of which package
2067 // made the remote request, and which remote connection service was used.
2068 if (extras.containsKey(
2069 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2070 Bundle newExtras = new Bundle();
2071 newExtras.putString(
2072 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2073 extras.getString(
2074 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME
2075 ));
2076 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2077 request.getAccountHandle());
2078 connection.putExtras(newExtras);
2079 }
2080 }
2081 } catch (UnsupportedOperationException ose) {
2082 // Do nothing; if the ConnectionService reported a failure it will be an instance
2083 // of an immutable Connection which we cannot edit, so we're out of luck.
2084 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002085 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002086
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002087 boolean isSelfManaged =
2088 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
2089 == Connection.PROPERTY_SELF_MANAGED;
2090 // Self-managed Connections should always use voip audio mode; we default here so that the
2091 // local state within the ConnectionService matches the default we assume in Telecom.
2092 if (isSelfManaged) {
2093 connection.setAudioModeIsVoip(true);
2094 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002095 connection.setTelecomCallId(callId);
Sungjae7f4137452020-09-16 17:01:54 +09002096 PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
2097 ? request.getAccountHandle() : connection.getPhoneAccountHandle();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002098 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Sungjae7f4137452020-09-16 17:01:54 +09002099 addConnection(phoneAccountHandle, callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07002100 }
2101
Andrew Lee100e2932014-09-08 15:34:24 -07002102 Uri address = connection.getAddress();
2103 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07002104 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002105 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002106 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07002107 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
2108 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002109
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002110 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07002111 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002112 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07002113 request,
2114 new ParcelableConnection(
Sungjae7f4137452020-09-16 17:01:54 +09002115 phoneAccountHandle,
Evan Charltonbf11f982014-07-20 22:06:28 -07002116 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002117 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002118 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002119 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07002120 connection.getAddress(),
2121 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07002122 connection.getCallerDisplayName(),
2123 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002124 connection.getVideoProvider() == null ?
2125 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002126 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07002127 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002128 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002129 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002130 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07002131 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002132 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002133 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002134 connection.getExtras(),
2135 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08002136
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002137 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002138 // Tell ConnectionService to show its incoming call UX.
2139 connection.onShowIncomingCallUi();
2140 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002141 if (isUnknown) {
2142 triggerConferenceRecalculate();
2143 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002144 }
2145
Tyler Gunn159f35c2017-03-02 09:28:37 -08002146 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
2147 final String callId, final ConnectionRequest request,
2148 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08002149
2150 Log.i(this, "createConnectionFailed %s", callId);
2151 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002152 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002153 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002154 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002155 }
2156 }
2157
Ravi Paluri80aa2142019-12-02 11:57:37 +05302158 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
2159 final String callId, final ConnectionRequest request,
2160 boolean isIncoming) {
2161
2162 Log.i(this, "createConferenceFailed %s", callId);
2163 if (isIncoming) {
2164 onCreateIncomingConferenceFailed(callManagerAccount, request);
2165 } else {
2166 onCreateOutgoingConferenceFailed(callManagerAccount, request);
2167 }
2168 }
2169
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08002170 private void handoverFailed(final String callId, final ConnectionRequest request,
2171 int reason) {
2172
2173 Log.i(this, "handoverFailed %s", callId);
2174 onHandoverFailed(request, reason);
2175 }
2176
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002177 /**
2178 * Called by Telecom when the creation of a new Connection has completed and it is now added
2179 * to Telecom.
2180 * @param callId The ID of the connection.
2181 */
2182 private void notifyCreateConnectionComplete(final String callId) {
2183 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07002184 if (callId == null) {
2185 // This could happen if the connection fails quickly and is removed from the
2186 // ConnectionService before Telecom sends the create connection complete callback.
2187 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
2188 return;
2189 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002190 onCreateConnectionComplete(findConnectionForAction(callId,
2191 "notifyCreateConnectionComplete"));
2192 }
2193
Ravi Paluri80aa2142019-12-02 11:57:37 +05302194 /**
2195 * Called by Telecom when the creation of a new Conference has completed and it is now added
2196 * to Telecom.
2197 * @param callId The ID of the connection.
2198 */
2199 private void notifyCreateConferenceComplete(final String callId) {
2200 Log.i(this, "notifyCreateConferenceComplete %s", callId);
2201 if (callId == null) {
2202 // This could happen if the conference fails quickly and is removed from the
2203 // ConnectionService before Telecom sends the create conference complete callback.
2204 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
2205 return;
2206 }
2207 onCreateConferenceComplete(findConferenceForAction(callId,
2208 "notifyCreateConferenceComplete"));
2209 }
2210
2211
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002212 private void abort(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002213 Log.i(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002214 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002215 }
2216
Tyler Gunnbe74de02014-08-29 14:51:48 -07002217 private void answerVideo(String callId, int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002218 Log.i(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302219 if (mConnectionById.containsKey(callId)) {
2220 findConnectionForAction(callId, "answer").onAnswer(videoState);
2221 } else {
2222 findConferenceForAction(callId, "answer").onAnswer(videoState);
2223 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002224 }
2225
Tyler Gunnbe74de02014-08-29 14:51:48 -07002226 private void answer(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002227 Log.i(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302228 if (mConnectionById.containsKey(callId)) {
2229 findConnectionForAction(callId, "answer").onAnswer();
2230 } else {
2231 findConferenceForAction(callId, "answer").onAnswer();
2232 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002233 }
2234
Pooja Jaind34698d2017-12-28 14:15:31 +05302235 private void deflect(String callId, Uri address) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002236 Log.i(this, "deflect %s", callId);
Pooja Jaind34698d2017-12-28 14:15:31 +05302237 findConnectionForAction(callId, "deflect").onDeflect(address);
2238 }
2239
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002240 private void reject(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002241 Log.i(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302242 if (mConnectionById.containsKey(callId)) {
2243 findConnectionForAction(callId, "reject").onReject();
2244 } else {
2245 findConferenceForAction(callId, "reject").onReject();
2246 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002247 }
2248
Bryce Lee81901682015-08-28 16:38:02 -07002249 private void reject(String callId, String rejectWithMessage) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002250 Log.i(this, "reject %s with message", callId);
Bryce Lee81901682015-08-28 16:38:02 -07002251 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2252 }
2253
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002254 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002255 Log.i(this, "reject %s with reason %d", callId, rejectReason);
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002256 findConnectionForAction(callId, "reject").onReject(rejectReason);
2257 }
2258
Ravi Palurif4b38e72020-02-05 12:35:41 +05302259 private void transfer(String callId, Uri number, boolean isConfirmationRequired) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002260 Log.i(this, "transfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302261 findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired);
2262 }
2263
2264 private void consultativeTransfer(String callId, String otherCallId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002265 Log.i(this, "consultativeTransfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302266 Connection connection1 = findConnectionForAction(callId, "consultativeTransfer");
2267 Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer");
2268 connection1.onTransfer(connection2);
2269 }
2270
Bryce Leecac50772015-11-17 15:13:29 -08002271 private void silence(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002272 Log.i(this, "silence %s", callId);
Bryce Leecac50772015-11-17 15:13:29 -08002273 findConnectionForAction(callId, "silence").onSilence();
2274 }
2275
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002276 private void disconnect(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002277 Log.i(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002278 if (mConnectionById.containsKey(callId)) {
2279 findConnectionForAction(callId, "disconnect").onDisconnect();
2280 } else {
2281 findConferenceForAction(callId, "disconnect").onDisconnect();
2282 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002283 }
2284
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002285 private void hold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002286 Log.i(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002287 if (mConnectionById.containsKey(callId)) {
2288 findConnectionForAction(callId, "hold").onHold();
2289 } else {
2290 findConferenceForAction(callId, "hold").onHold();
2291 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002292 }
2293
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002294 private void unhold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002295 Log.i(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002296 if (mConnectionById.containsKey(callId)) {
2297 findConnectionForAction(callId, "unhold").onUnhold();
2298 } else {
2299 findConferenceForAction(callId, "unhold").onUnhold();
2300 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002301 }
2302
Yorke Lee4af59352015-05-13 14:14:54 -07002303 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002304 Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002305 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002306 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2307 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002308 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002309 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2310 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002311 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002312 }
2313
Grace Jiae99fde92021-01-19 14:58:01 -08002314 private void onUsingAlternativeUi(String callId, boolean isUsingAlternativeUi) {
2315 Log.i(this, "onUsingAlternativeUi %s %s", callId, isUsingAlternativeUi);
2316 if (mConnectionById.containsKey(callId)) {
2317 findConnectionForAction(callId, "onUsingAlternativeUi")
2318 .onUsingAlternativeUi(isUsingAlternativeUi);
2319 }
2320 }
2321
2322 private void onTrackedByNonUiService(String callId, boolean isTracked) {
2323 Log.i(this, "onTrackedByNonUiService %s %s", callId, isTracked);
2324 if (mConnectionById.containsKey(callId)) {
2325 findConnectionForAction(callId, "onTrackedByNonUiService")
2326 .onTrackedByNonUiService(isTracked);
2327 }
2328 }
2329
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002330 private void playDtmfTone(String callId, char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002331 Log.i(this, "playDtmfTone %s %c", callId, digit);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002332 if (mConnectionById.containsKey(callId)) {
2333 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2334 } else {
2335 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2336 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002337 }
2338
2339 private void stopDtmfTone(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002340 Log.i(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002341 if (mConnectionById.containsKey(callId)) {
2342 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2343 } else {
2344 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2345 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002346 }
2347
Santos Cordon823fd3c2014-08-07 18:35:18 -07002348 private void conference(String callId1, String callId2) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002349 Log.i(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002350
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002351 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002352 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002353 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002354 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002355 conference2 = findConferenceForAction(callId2, "conference");
2356 if (conference2 == getNullConference()) {
2357 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2358 callId2);
2359 return;
2360 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002361 }
Santos Cordonb6939982014-06-04 20:20:58 -07002362
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002363 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002364 Connection connection1 = findConnectionForAction(callId1, "conference");
2365 if (connection1 == getNullConnection()) {
2366 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2367 if (conference1 == getNullConference()) {
2368 Log.w(this,
2369 "Connection1 or Conference1 missing in conference request %s.",
2370 callId1);
2371 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002372 // Call 1 is a conference.
2373 if (connection2 != getNullConnection()) {
2374 // Call 2 is a connection so merge via call 1 (conference).
2375 conference1.onMerge(connection2);
2376 } else {
2377 // Call 2 is ALSO a conference; this should never happen.
2378 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2379 "merge two conferences.");
2380 return;
2381 }
Ihab Awad50e35062014-09-30 09:17:03 -07002382 }
2383 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002384 // Call 1 is a connection.
2385 if (conference2 != getNullConference()) {
2386 // Call 2 is a conference, so merge via call 2.
2387 conference2.onMerge(connection1);
2388 } else {
2389 // Call 2 is a connection, so merge together.
2390 onConference(connection1, connection2);
2391 }
Ihab Awad50e35062014-09-30 09:17:03 -07002392 }
Santos Cordon980acb92014-05-31 10:31:19 -07002393 }
2394
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002395 private void splitFromConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002396 Log.i(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002397
2398 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002399 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002400 Log.w(this, "Connection missing in conference request %s.", callId);
2401 return;
2402 }
2403
Santos Cordon0159ac02014-08-21 14:28:11 -07002404 Conference conference = connection.getConference();
2405 if (conference != null) {
2406 conference.onSeparate(connection);
2407 }
Santos Cordon980acb92014-05-31 10:31:19 -07002408 }
2409
Santos Cordona4868042014-09-04 17:39:22 -07002410 private void mergeConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002411 Log.i(this, "mergeConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002412 Conference conference = findConferenceForAction(callId, "mergeConference");
2413 if (conference != null) {
2414 conference.onMerge();
2415 }
2416 }
2417
2418 private void swapConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002419 Log.i(this, "swapConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002420 Conference conference = findConferenceForAction(callId, "swapConference");
2421 if (conference != null) {
2422 conference.onSwap();
2423 }
2424 }
2425
Ravi Paluri404babb2020-01-23 19:02:44 +05302426 private void addConferenceParticipants(String callId, List<Uri> participants) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002427 Log.i(this, "addConferenceParticipants(%s)", callId);
Ravi Paluri404babb2020-01-23 19:02:44 +05302428 if (mConnectionById.containsKey(callId)) {
2429 findConnectionForAction(callId, "addConferenceParticipants")
2430 .onAddConferenceParticipants(participants);
2431 } else {
2432 findConferenceForAction(callId, "addConferenceParticipants")
2433 .onAddConferenceParticipants(participants);
2434 }
2435 }
2436
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002437 /**
2438 * Notifies a {@link Connection} of a request to pull an external call.
2439 *
2440 * See {@link Call#pullExternalCall()}.
2441 *
2442 * @param callId The ID of the call to pull.
2443 */
2444 private void pullExternalCall(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002445 Log.i(this, "pullExternalCall(%s)", callId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002446 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2447 if (connection != null) {
2448 connection.onPullExternalCall();
2449 }
2450 }
2451
2452 /**
2453 * Notifies a {@link Connection} of a call event.
2454 *
2455 * See {@link Call#sendCallEvent(String, Bundle)}.
2456 *
2457 * @param callId The ID of the call receiving the event.
2458 * @param event The event.
2459 * @param extras Extras associated with the event.
2460 */
2461 private void sendCallEvent(String callId, String event, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002462 Log.i(this, "sendCallEvent(%s, %s)", callId, event);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002463 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2464 if (connection != null) {
2465 connection.onCallEvent(event, extras);
2466 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002467 }
2468
Hall Liu5efe9972021-02-04 13:09:45 -08002469 private void onCallFilteringCompleted(String callId, boolean isBlocked, boolean isInContacts,
2470 CallScreeningService.ParcelableCallResponse callScreeningResponse,
2471 boolean isResponseFromSystemDialer) {
2472 Log.i(this, "onCallFilteringCompleted(%s, %b, %b, %s, %b)", callId,
2473 isBlocked, isInContacts, callScreeningResponse, isResponseFromSystemDialer);
Hall Liu49cabcc2021-01-15 11:41:48 -08002474 Connection connection = findConnectionForAction(callId, "onCallFilteringCompleted");
2475 if (connection != null) {
Hall Liu5efe9972021-02-04 13:09:45 -08002476 connection.onCallFilteringCompleted(isBlocked, isInContacts,
2477 callScreeningResponse == null ? null : callScreeningResponse.toCallResponse(),
2478 isResponseFromSystemDialer);
Hall Liu49cabcc2021-01-15 11:41:48 -08002479 }
2480 }
2481
Tyler Gunndee56a82016-03-23 16:06:34 -07002482 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002483 * Notifies a {@link Connection} that a handover has completed.
2484 *
2485 * @param callId The ID of the call which completed handover.
2486 */
2487 private void notifyHandoverComplete(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002488 Log.i(this, "notifyHandoverComplete(%s)", callId);
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002489 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2490 if (connection != null) {
2491 connection.onHandoverComplete();
2492 }
2493 }
2494
2495 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002496 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2497 * <p>
2498 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2499 * the {@link android.telecom.Call#putExtra(String, boolean)},
2500 * {@link android.telecom.Call#putExtra(String, int)},
2501 * {@link android.telecom.Call#putExtra(String, String)},
2502 * {@link Call#removeExtras(List)}.
2503 *
2504 * @param callId The ID of the call receiving the event.
2505 * @param extras The new extras bundle.
2506 */
2507 private void handleExtrasChanged(String callId, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002508 Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002509 if (mConnectionById.containsKey(callId)) {
2510 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2511 } else if (mConferenceById.containsKey(callId)) {
2512 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2513 }
2514 }
2515
Hall Liub64ac4c2017-02-06 10:49:48 -08002516 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002517 Log.i(this, "startRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002518 if (mConnectionById.containsKey(callId)) {
2519 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2520 } else if (mConferenceById.containsKey(callId)) {
2521 Log.w(this, "startRtt called on a conference.");
2522 }
2523 }
2524
2525 private void stopRtt(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002526 Log.i(this, "stopRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002527 if (mConnectionById.containsKey(callId)) {
2528 findConnectionForAction(callId, "stopRtt").onStopRtt();
2529 } else if (mConferenceById.containsKey(callId)) {
2530 Log.w(this, "stopRtt called on a conference.");
2531 }
2532 }
2533
2534 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002535 Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
Hall Liub64ac4c2017-02-06 10:49:48 -08002536 if (mConnectionById.containsKey(callId)) {
2537 findConnectionForAction(callId, "handleRttUpgradeResponse")
2538 .handleRttUpgradeResponse(rttTextStream);
2539 } else if (mConferenceById.containsKey(callId)) {
2540 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2541 }
2542 }
2543
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002544 private void onPostDialContinue(String callId, boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002545 Log.i(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002546 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002547 }
2548
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002549 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002550 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002551 // No need to query again if we already did it.
2552 return;
2553 }
2554
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002555 String callingPackage = getOpPackageName();
2556
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002557 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002558 @Override
2559 public void onResult(
2560 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002561 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002562 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002563 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002564 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002565 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002566 mRemoteConnectionManager.addConnectionService(
2567 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002568 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002569 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002570 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002571 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002572 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002573 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002574 }
2575
2576 @Override
2577 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002578 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002579 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002580 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002581 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002582 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002583 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002584 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002585 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002586 }
2587
Ihab Awadf8b69882014-07-25 15:14:01 -07002588 /**
2589 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002590 * incoming request. This is used by {@code ConnectionService}s that are registered with
2591 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2592 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002593 *
2594 * @param connectionManagerPhoneAccount See description at
2595 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2596 * @param request Details about the incoming call.
2597 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2598 * not handle the call.
2599 */
2600 public final RemoteConnection createRemoteIncomingConnection(
2601 PhoneAccountHandle connectionManagerPhoneAccount,
2602 ConnectionRequest request) {
2603 return mRemoteConnectionManager.createRemoteConnection(
2604 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002605 }
2606
2607 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002608 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002609 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2610 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2611 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002612 *
2613 * @param connectionManagerPhoneAccount See description at
2614 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002615 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002616 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2617 * not handle the call.
2618 */
2619 public final RemoteConnection createRemoteOutgoingConnection(
2620 PhoneAccountHandle connectionManagerPhoneAccount,
2621 ConnectionRequest request) {
2622 return mRemoteConnectionManager.createRemoteConnection(
2623 connectionManagerPhoneAccount, request, false);
2624 }
2625
2626 /**
Grace Jia9a09c672020-08-04 12:52:09 -07002627 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2628 * incoming request. This is used by {@code ConnectionService}s that are registered with
2629 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2630 *
2631 * @param connectionManagerPhoneAccount See description at
2632 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2633 * @param request Details about the incoming conference call.
2634 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2635 * handle the call.
2636 */
2637 public final @Nullable RemoteConference createRemoteIncomingConference(
2638 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2639 @Nullable ConnectionRequest request) {
2640 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2641 request, true);
2642 }
2643
2644 /**
2645 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2646 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2647 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2648 *
2649 * @param connectionManagerPhoneAccount See description at
2650 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2651 * @param request Details about the outgoing conference call.
2652 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2653 * handle the call.
2654 */
2655 public final @Nullable RemoteConference createRemoteOutgoingConference(
2656 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2657 @Nullable ConnectionRequest request) {
2658 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2659 request, false);
2660 }
2661
2662 /**
Santos Cordona663f862014-10-29 13:49:58 -07002663 * Indicates to the relevant {@code RemoteConnectionService} that the specified
2664 * {@link RemoteConnection}s should be merged into a conference call.
2665 * <p>
2666 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
2667 * be invoked.
2668 *
2669 * @param remoteConnection1 The first of the remote connections to conference.
2670 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07002671 */
2672 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07002673 RemoteConnection remoteConnection1,
2674 RemoteConnection remoteConnection2) {
2675 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07002676 }
2677
2678 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002679 * Adds a new conference call. When a conference call is created either as a result of an
2680 * explicit request via {@link #onConference} or otherwise, the connection service should supply
2681 * an instance of {@link Conference} by invoking this method. A conference call provided by this
2682 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
2683 *
2684 * @param conference The new conference object.
2685 */
2686 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07002687 Log.d(this, "addConference: conference=%s", conference);
2688
Santos Cordon823fd3c2014-08-07 18:35:18 -07002689 String id = addConferenceInternal(conference);
2690 if (id != null) {
2691 List<String> connectionIds = new ArrayList<>(2);
2692 for (Connection connection : conference.getConnections()) {
2693 if (mIdByConnection.containsKey(connection)) {
2694 connectionIds.add(mIdByConnection.get(connection));
2695 }
2696 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002697 conference.setTelecomCallId(id);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07002698 ParcelableConference parcelableConference = new ParcelableConference.Builder(
2699 conference.getPhoneAccountHandle(), conference.getState())
2700 .setConnectionCapabilities(conference.getConnectionCapabilities())
2701 .setConnectionProperties(conference.getConnectionProperties())
2702 .setConnectionIds(connectionIds)
2703 .setVideoAttributes(conference.getVideoProvider() == null
2704 ? null : conference.getVideoProvider().getInterface(),
2705 conference.getVideoState())
2706 .setConnectTimeMillis(conference.getConnectTimeMillis(),
2707 conference.getConnectionStartElapsedRealtimeMillis())
2708 .setStatusHints(conference.getStatusHints())
2709 .setExtras(conference.getExtras())
2710 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2711 .setCallerDisplayName(conference.getCallerDisplayName(),
2712 conference.getCallerDisplayNamePresentation())
2713 .setDisconnectCause(conference.getDisconnectCause())
2714 .setRingbackRequested(conference.isRingbackRequested())
2715 .setCallDirection(conference.getCallDirection())
2716 .build();
Andrew Lee0f51da32015-04-16 13:11:55 -07002717
Santos Cordon823fd3c2014-08-07 18:35:18 -07002718 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07002719 mAdapter.setVideoProvider(id, conference.getVideoProvider());
2720 mAdapter.setVideoState(id, conference.getVideoState());
Tyler Gunn10362372020-04-08 13:12:30 -07002721 // In some instances a conference can start its life as a standalone call with just a
2722 // single participant; ensure we signal to Telecom in this case.
2723 if (!conference.isMultiparty()) {
2724 mAdapter.setConferenceState(id, conference.isMultiparty());
2725 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002726
2727 // Go through any child calls and set the parent.
2728 for (Connection connection : conference.getConnections()) {
2729 String connectionId = mIdByConnection.get(connection);
2730 if (connectionId != null) {
2731 mAdapter.setIsConferenced(connectionId, id);
2732 }
2733 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002734 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002735 }
2736 }
2737
2738 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002739 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
2740 * connection.
2741 *
2742 * @param phoneAccountHandle The phone account handle for the connection.
2743 * @param connection The connection to add.
2744 */
2745 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
2746 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07002747 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
2748 }
2749
2750 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002751 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
2752 * microphone, camera).
2753 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08002754 * <p>
2755 * The {@link ConnectionService} will be disconnected when it failed to call this method within
2756 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
2757 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08002758 * @see ConnectionService#onConnectionServiceFocusLost()
2759 */
2760 public final void connectionServiceFocusReleased() {
2761 mAdapter.onConnectionServiceFocusReleased();
2762 }
2763
2764 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07002765 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07002766 * connection, as well as adding that connection to the specified conference.
2767 * <p>
2768 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
2769 * IMS conference participants to be added to a conference in a single step; this helps ensure
2770 * UI updates happen atomically, rather than adding the connection and then adding it to
2771 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07002772 *
2773 * @param phoneAccountHandle The phone account handle for the connection.
2774 * @param connection The connection to add.
2775 * @param conference The parent conference of the new connection.
2776 * @hide
2777 */
Tyler Gunn5567d742019-10-31 13:04:37 -07002778 @SystemApi
2779 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
2780 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002781
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002782 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002783 if (id != null) {
2784 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07002785 String conferenceId = null;
2786 if (conference != null) {
2787 conferenceId = mIdByConference.get(conference);
2788 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002789
2790 ParcelableConnection parcelableConnection = new ParcelableConnection(
2791 phoneAccountHandle,
2792 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002793 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002794 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002795 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002796 connection.getAddress(),
2797 connection.getAddressPresentation(),
2798 connection.getCallerDisplayName(),
2799 connection.getCallerDisplayNamePresentation(),
2800 connection.getVideoProvider() == null ?
2801 null : connection.getVideoProvider().getInterface(),
2802 connection.getVideoState(),
2803 connection.isRingbackRequested(),
2804 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002805 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002806 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002807 connection.getStatusHints(),
2808 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002809 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07002810 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07002811 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002812 connection.getCallDirection(),
2813 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002814 mAdapter.addExistingConnection(id, parcelableConnection);
2815 }
2816 }
2817
2818 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002819 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
2820 * has taken responsibility.
2821 *
2822 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07002823 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07002824 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07002825 return mConnectionById.values();
2826 }
2827
2828 /**
Santos Cordona6018b92016-02-16 14:23:12 -08002829 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
2830 * has taken responsibility.
2831 *
2832 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
2833 */
2834 public final Collection<Conference> getAllConferences() {
2835 return mConferenceById.values();
2836 }
2837
2838 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002839 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2840 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07002841 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002842 * @param connectionManagerPhoneAccount See description at
2843 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2844 * @param request Details about the incoming call.
2845 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2846 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002847 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002848 public Connection onCreateIncomingConnection(
2849 PhoneAccountHandle connectionManagerPhoneAccount,
2850 ConnectionRequest request) {
2851 return null;
2852 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302853 /**
Grace Jia8587ee52020-07-10 15:42:32 -07002854 * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
2855 * conference call initiated via
2856 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302857 *
2858 * @param connectionManagerPhoneAccount See description at
2859 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Grace Jia8587ee52020-07-10 15:42:32 -07002860 * @param request Details about the incoming conference call.
2861 * @return The {@code Conference} object to satisfy this call, or {@code null} to
Ravi Paluri80aa2142019-12-02 11:57:37 +05302862 * not handle the call.
2863 */
2864 public @Nullable Conference onCreateIncomingConference(
2865 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2866 @Nullable ConnectionRequest request) {
2867 return null;
2868 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002869
2870 /**
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002871 * Called after the {@link Connection} returned by
2872 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
2873 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
2874 * added to the {@link ConnectionService} and sent to Telecom.
2875 *
2876 * @param connection the {@link Connection}.
2877 * @hide
2878 */
2879 public void onCreateConnectionComplete(Connection connection) {
2880 }
2881
2882 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302883 * Called after the {@link Conference} returned by
2884 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
2885 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
2886 * added to the {@link ConnectionService} and sent to Telecom.
2887 *
2888 * @param conference the {@link Conference}.
2889 * @hide
2890 */
2891 public void onCreateConferenceComplete(Conference conference) {
2892 }
2893
2894
2895 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002896 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2897 * incoming {@link Connection} was denied.
2898 * <p>
2899 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2900 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
2901 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2902 * {@link Connection}.
2903 * <p>
2904 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2905 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002906 * @param connectionManagerPhoneAccount See description at
2907 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002908 * @param request The incoming connection request.
2909 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002910 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2911 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002912 }
2913
2914 /**
2915 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2916 * outgoing {@link Connection} was denied.
2917 * <p>
2918 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2919 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
2920 * The {@link ConnectionService} is responisible for informing the user that the
2921 * {@link Connection} cannot be made at this time.
2922 * <p>
2923 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2924 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002925 * @param connectionManagerPhoneAccount See description at
2926 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002927 * @param request The outgoing connection request.
2928 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002929 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2930 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002931 }
2932
2933 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302934 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2935 * incoming {@link Conference} was denied.
2936 * <p>
2937 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2938 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
2939 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2940 * {@link Conference}.
2941 * <p>
2942 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2943 *
2944 * @param connectionManagerPhoneAccount See description at
2945 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2946 * @param request The incoming connection request.
2947 */
2948 public void onCreateIncomingConferenceFailed(
2949 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2950 @Nullable ConnectionRequest request) {
2951 }
2952
2953 /**
2954 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2955 * outgoing {@link Conference} was denied.
2956 * <p>
2957 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2958 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
2959 * The {@link ConnectionService} is responisible for informing the user that the
2960 * {@link Conference} cannot be made at this time.
2961 * <p>
2962 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2963 *
2964 * @param connectionManagerPhoneAccount See description at
2965 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2966 * @param request The outgoing connection request.
2967 */
2968 public void onCreateOutgoingConferenceFailed(
2969 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2970 @Nullable ConnectionRequest request) {
2971 }
2972
2973
2974 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002975 * Trigger recalculate functinality for conference calls. This is used when a Telephony
2976 * Connection is part of a conference controller but is not yet added to Connection
2977 * Service and hence cannot be added to the conference call.
2978 *
2979 * @hide
2980 */
2981 public void triggerConferenceRecalculate() {
2982 }
2983
2984 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002985 * Create a {@code Connection} given an outgoing request. This is used to initiate new
2986 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002987 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002988 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2989 * this call.
2990 * <p>
2991 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2992 * has registered one or more {@code PhoneAccount}s having
2993 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2994 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2995 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2996 * making the connection.
2997 * <p>
2998 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2999 * being asked to make a direct connection. The
3000 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3001 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3002 * making the connection.
3003 * @param request Details about the outgoing call.
3004 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07003005 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07003006 */
Ihab Awadf8b69882014-07-25 15:14:01 -07003007 public Connection onCreateOutgoingConnection(
3008 PhoneAccountHandle connectionManagerPhoneAccount,
3009 ConnectionRequest request) {
3010 return null;
3011 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003012
3013 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05303014 * Create a {@code Conference} given an outgoing request. This is used to initiate new
Grace Jia8587ee52020-07-10 15:42:32 -07003015 * outgoing conference call requested via
3016 * {@link TelecomManager#startConference(List, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303017 *
3018 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3019 * this call.
3020 * <p>
3021 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
3022 * has registered one or more {@code PhoneAccount}s having
3023 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
3024 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
3025 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
3026 * making the connection.
3027 * <p>
3028 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
3029 * being asked to make a direct connection. The
3030 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3031 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3032 * making the connection.
3033 * @param request Details about the outgoing call.
3034 * @return The {@code Conference} object to satisfy this call, or the result of an invocation
3035 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
3036 */
3037 public @Nullable Conference onCreateOutgoingConference(
3038 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
3039 @Nullable ConnectionRequest request) {
3040 return null;
3041 }
3042
3043
3044 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003045 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3046 * outgoing handover {@link Connection}.
3047 * <p>
3048 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3049 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3050 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3051 * is referred to as the source of the handover, and the video calling app is referred to as the
3052 * destination.
3053 * <p>
3054 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3055 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3056 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3057 * device.
3058 * <p>
3059 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
3060 * device when the user initiates a handover request from one app to another. The user request
3061 * originates in the {@link InCallService} via
3062 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3063 * <p>
3064 * For a full discussion of the handover process and the APIs involved, see
3065 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3066 * <p>
3067 * Implementations of this method should return an instance of {@link Connection} which
3068 * represents the handover. If your app does not wish to accept a handover to it at this time,
3069 * you can return {@code null}. The code below shows an example of how this is done.
3070 * <pre>
3071 * {@code
3072 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3073 * fromPhoneAccountHandle, ConnectionRequest request) {
3074 * if (!isHandoverAvailable()) {
3075 * return null;
3076 * }
3077 * MyConnection connection = new MyConnection();
3078 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3079 * connection.setVideoState(request.getVideoState());
3080 * return connection;
3081 * }
3082 * }
3083 * </pre>
3084 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003085 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3086 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08003087 * @param request Details about the call to handover.
3088 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003089 */
3090 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3091 ConnectionRequest request) {
3092 return null;
3093 }
3094
3095 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003096 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3097 * incoming handover {@link Connection}.
3098 * <p>
3099 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3100 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3101 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3102 * is referred to as the source of the handover, and the video calling app is referred to as the
3103 * destination.
3104 * <p>
3105 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3106 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3107 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3108 * device.
3109 * <p>
3110 * This method is called on the destination app on the <em>receiving</em> device when the
3111 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
3112 * accept an incoming handover from the <em>initiating</em> device.
3113 * <p>
3114 * For a full discussion of the handover process and the APIs involved, see
3115 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3116 * <p>
3117 * Implementations of this method should return an instance of {@link Connection} which
3118 * represents the handover. The code below shows an example of how this is done.
3119 * <pre>
3120 * {@code
3121 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3122 * fromPhoneAccountHandle, ConnectionRequest request) {
3123 * // Given that your app requested to accept the handover, you should not return null here.
3124 * MyConnection connection = new MyConnection();
3125 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3126 * connection.setVideoState(request.getVideoState());
3127 * return connection;
3128 * }
3129 * }
3130 * </pre>
3131 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003132 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3133 * ConnectionService which needs to handover the call.
3134 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08003135 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003136 */
3137 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3138 ConnectionRequest request) {
3139 return null;
3140 }
3141
3142 /**
3143 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
3144 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08003145 * <p>
3146 * For a full discussion of the handover process and the APIs involved, see
3147 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
3148 *
3149 * @param request Details about the call which failed to handover.
3150 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07003151 */
Tyler Gunn9d127732018-03-02 15:45:51 -08003152 public void onHandoverFailed(ConnectionRequest request,
3153 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07003154 return;
3155 }
3156
3157 /**
Yorke Leec3cf9822014-10-02 09:38:39 -07003158 * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
3159 * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
3160 * call created using
3161 * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
3162 *
Yorke Lee770ed6e2014-10-06 18:58:52 -07003163 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07003164 */
3165 public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
3166 ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003167 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07003168 }
3169
3170 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003171 * Conference two specified connections. Invoked when the user has made a request to merge the
3172 * specified connections into a conference call. In response, the connection service should
3173 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07003174 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07003175 * @param connection1 A connection to merge into a conference call.
3176 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07003177 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07003178 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07003179
Santos Cordona663f862014-10-29 13:49:58 -07003180 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07003181 * Called when a connection is added.
3182 * @hide
3183 */
3184 public void onConnectionAdded(Connection connection) {}
3185
3186 /**
3187 * Called when a connection is removed.
3188 * @hide
3189 */
3190 public void onConnectionRemoved(Connection connection) {}
3191
3192 /**
3193 * Called when a conference is added.
3194 * @hide
3195 */
3196 public void onConferenceAdded(Conference conference) {}
3197
3198 /**
3199 * Called when a conference is removed.
3200 * @hide
3201 */
3202 public void onConferenceRemoved(Conference conference) {}
3203
3204 /**
Santos Cordona663f862014-10-29 13:49:58 -07003205 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
3206 * When this method is invoked, this {@link ConnectionService} should create its own
3207 * representation of the conference call and send it to telecom using {@link #addConference}.
3208 * <p>
3209 * This is only relevant to {@link ConnectionService}s which are registered with
3210 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
3211 *
3212 * @param conference The remote conference call.
3213 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07003214 public void onRemoteConferenceAdded(RemoteConference conference) {}
3215
Santos Cordon823fd3c2014-08-07 18:35:18 -07003216 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003217 * Called when an existing connection is added remotely.
3218 * @param connection The existing connection which was added.
3219 */
3220 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
3221
3222 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003223 * Called when the {@link ConnectionService} has lost the call focus.
3224 * The {@link ConnectionService} should release the call resources and invokes
3225 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
3226 * released the call resources.
3227 */
3228 public void onConnectionServiceFocusLost() {}
3229
3230 /**
3231 * Called when the {@link ConnectionService} has gained the call focus. The
3232 * {@link ConnectionService} can acquire the call resources at this time.
3233 */
3234 public void onConnectionServiceFocusGained() {}
3235
3236 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003237 * @hide
3238 */
3239 public boolean containsConference(Conference conference) {
3240 return mIdByConference.containsKey(conference);
3241 }
3242
Ihab Awadb8e85c72014-08-23 20:34:57 -07003243 /** {@hide} */
3244 void addRemoteConference(RemoteConference remoteConference) {
3245 onRemoteConferenceAdded(remoteConference);
3246 }
3247
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003248 /** {@hide} */
3249 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
3250 onRemoteExistingConnectionAdded(remoteConnection);
3251 }
3252
Ihab Awad5d0410f2014-07-30 10:07:40 -07003253 private void onAccountsInitialized() {
3254 mAreAccountsInitialized = true;
3255 for (Runnable r : mPreInitializationConnectionRequests) {
3256 r.run();
3257 }
3258 mPreInitializationConnectionRequests.clear();
3259 }
3260
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003261 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003262 * Adds an existing connection to the list of connections, identified by a new call ID unique
3263 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003264 *
3265 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003266 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003267 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003268 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
3269 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003270
3271 if (connection.getExtras() != null && connection.getExtras()
3272 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3273 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3274 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
3275 connection.getTelecomCallId(), id);
3276 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003277 // If no phone account handle was provided, we cannot be sure the call ID is unique,
3278 // so just use a random UUID.
3279 id = UUID.randomUUID().toString();
3280 } else {
3281 // Phone account handle was provided, so use the ConnectionService class name as a
3282 // prefix for a unique incremental call ID.
3283 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
3284 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003285 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003286 return id;
3287 }
3288
Pengquan Meng70c9885332017-10-02 18:09:03 -07003289 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003290 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003291 mConnectionById.put(callId, connection);
3292 mIdByConnection.put(connection, callId);
3293 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003294 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003295 connection.setPhoneAccountHandle(handle);
3296 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003297 }
3298
Anthony Lee30e65842014-11-06 16:30:53 -08003299 /** {@hide} */
3300 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003301 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003302 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003303 String id = mIdByConnection.get(connection);
3304 if (id != null) {
3305 mConnectionById.remove(id);
3306 mIdByConnection.remove(connection);
3307 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003308 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003309 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003310 }
3311
Santos Cordon823fd3c2014-08-07 18:35:18 -07003312 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003313 String originalId = null;
3314 if (conference.getExtras() != null && conference.getExtras()
3315 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3316 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3317 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3318 conference.getTelecomCallId(),
3319 originalId);
3320 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003321 if (mIdByConference.containsKey(conference)) {
3322 Log.w(this, "Re-adding an existing conference: %s.", conference);
3323 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003324 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3325 // cannot determine a ConnectionService class name to associate with the ID, so use
3326 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003327 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003328 mConferenceById.put(id, conference);
3329 mIdByConference.put(conference, id);
3330 conference.addListener(mConferenceListener);
3331 return id;
3332 }
3333
3334 return null;
3335 }
3336
3337 private void removeConference(Conference conference) {
3338 if (mIdByConference.containsKey(conference)) {
3339 conference.removeListener(mConferenceListener);
3340
3341 String id = mIdByConference.get(conference);
3342 mConferenceById.remove(id);
3343 mIdByConference.remove(conference);
3344 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003345
3346 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003347 }
3348 }
3349
Ihab Awad542e0ea2014-05-16 10:22:16 -07003350 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003351 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003352 return mConnectionById.get(callId);
3353 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003354 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003355 return getNullConnection();
3356 }
3357
3358 static synchronized Connection getNullConnection() {
3359 if (sNullConnection == null) {
3360 sNullConnection = new Connection() {};
3361 }
3362 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003363 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003364
3365 private Conference findConferenceForAction(String conferenceId, String action) {
3366 if (mConferenceById.containsKey(conferenceId)) {
3367 return mConferenceById.get(conferenceId);
3368 }
3369 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3370 return getNullConference();
3371 }
3372
Ihab Awadb8e85c72014-08-23 20:34:57 -07003373 private List<String> createConnectionIdList(List<Connection> connections) {
3374 List<String> ids = new ArrayList<>();
3375 for (Connection c : connections) {
3376 if (mIdByConnection.containsKey(c)) {
3377 ids.add(mIdByConnection.get(c));
3378 }
3379 }
3380 Collections.sort(ids);
3381 return ids;
3382 }
3383
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003384 /**
3385 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003386 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003387 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003388 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003389 * @return List of string conference and call Ids.
3390 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003391 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003392 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003393 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003394 // Only allow Connection and Conference conferenceables.
3395 if (c instanceof Connection) {
3396 Connection connection = (Connection) c;
3397 if (mIdByConnection.containsKey(connection)) {
3398 ids.add(mIdByConnection.get(connection));
3399 }
3400 } else if (c instanceof Conference) {
3401 Conference conference = (Conference) c;
3402 if (mIdByConference.containsKey(conference)) {
3403 ids.add(mIdByConference.get(conference));
3404 }
3405 }
3406 }
3407 Collections.sort(ids);
3408 return ids;
3409 }
3410
Santos Cordon0159ac02014-08-21 14:28:11 -07003411 private Conference getNullConference() {
3412 if (sNullConference == null) {
3413 sNullConference = new Conference(null) {};
3414 }
3415 return sNullConference;
3416 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003417
3418 private void endAllConnections() {
3419 // Unbound from telecomm. We should end all connections and conferences.
3420 for (Connection connection : mIdByConnection.keySet()) {
3421 // only operate on top-level calls. Conference calls will be removed on their own.
3422 if (connection.getConference() == null) {
3423 connection.onDisconnect();
3424 }
3425 }
3426 for (Conference conference : mIdByConference.keySet()) {
3427 conference.onDisconnect();
3428 }
3429 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003430
3431 /**
3432 * Retrieves the next call ID as maintainted by the connection service.
3433 *
3434 * @return The call ID.
3435 */
3436 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003437 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003438 return ++mId;
3439 }
3440 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003441
3442 /**
3443 * Returns this handler, ONLY FOR TESTING.
3444 * @hide
3445 */
3446 @VisibleForTesting
3447 public Handler getHandler() {
3448 return mHandler;
3449 }
Santos Cordon980acb92014-05-31 10:31:19 -07003450}