blob: 580513c12453bd0ba3a409a4fe3d348343b33c99 [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 Jia4e8dc102021-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";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800152 private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700153 private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
Hall Liub64ac4c2017-02-06 10:49:48 -0800154 private static final String SESSION_START_RTT = "CS.+RTT";
Hall Liua549fed2018-02-09 16:40:03 -0800155 private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
Hall Liub64ac4c2017-02-06 10:49:48 -0800156 private static final String SESSION_STOP_RTT = "CS.-RTT";
157 private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
Pengquan Meng731c1a32017-11-21 18:01:13 -0800158 private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
159 private static final String SESSION_CONNECTION_SERVICE_FOCUS_GAINED = "CS.cSFG";
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800160 private static final String SESSION_HANDOVER_FAILED = "CS.haF";
Ravi Paluri80aa2142019-12-02 11:57:37 +0530161 private static final String SESSION_CREATE_CONF = "CS.crConf";
162 private static final String SESSION_CREATE_CONF_COMPLETE = "CS.crConfC";
163 private static final String SESSION_CREATE_CONF_FAILED = "CS.crConfF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700164
Ihab Awad8aecfed2014-08-08 17:06:11 -0700165 private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700166 private static final int MSG_CREATE_CONNECTION = 2;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700167 private static final int MSG_ABORT = 3;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700168 private static final int MSG_ANSWER = 4;
169 private static final int MSG_REJECT = 5;
170 private static final int MSG_DISCONNECT = 6;
171 private static final int MSG_HOLD = 7;
172 private static final int MSG_UNHOLD = 8;
Yorke Lee4af59352015-05-13 14:14:54 -0700173 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700174 private static final int MSG_PLAY_DTMF_TONE = 10;
175 private static final int MSG_STOP_DTMF_TONE = 11;
176 private static final int MSG_CONFERENCE = 12;
177 private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700178 private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700179 private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
Tyler Gunnbe74de02014-08-29 14:51:48 -0700180 private static final int MSG_ANSWER_VIDEO = 17;
Santos Cordona4868042014-09-04 17:39:22 -0700181 private static final int MSG_MERGE_CONFERENCE = 18;
182 private static final int MSG_SWAP_CONFERENCE = 19;
Bryce Lee81901682015-08-28 16:38:02 -0700183 private static final int MSG_REJECT_WITH_MESSAGE = 20;
Bryce Leecac50772015-11-17 15:13:29 -0800184 private static final int MSG_SILENCE = 21;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700185 private static final int MSG_PULL_EXTERNAL_CALL = 22;
186 private static final int MSG_SEND_CALL_EVENT = 23;
Tyler Gunndee56a82016-03-23 16:06:34 -0700187 private static final int MSG_ON_EXTRAS_CHANGED = 24;
Tyler Gunn44e01912017-01-31 10:49:05 -0800188 private static final int MSG_CREATE_CONNECTION_FAILED = 25;
Hall Liub64ac4c2017-02-06 10:49:48 -0800189 private static final int MSG_ON_START_RTT = 26;
190 private static final int MSG_ON_STOP_RTT = 27;
191 private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700192 private static final int MSG_CREATE_CONNECTION_COMPLETE = 29;
Pengquan Meng731c1a32017-11-21 18:01:13 -0800193 private static final int MSG_CONNECTION_SERVICE_FOCUS_LOST = 30;
194 private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800195 private static final int MSG_HANDOVER_FAILED = 32;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800196 private static final int MSG_HANDOVER_COMPLETE = 33;
Pooja Jaind34698d2017-12-28 14:15:31 +0530197 private static final int MSG_DEFLECT = 34;
Ravi Paluri80aa2142019-12-02 11:57:37 +0530198 private static final int MSG_CREATE_CONFERENCE = 35;
199 private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
200 private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800201 private static final int MSG_REJECT_WITH_REASON = 38;
Ravi Paluri404babb2020-01-23 19:02:44 +0530202 private static final int MSG_ADD_PARTICIPANT = 39;
Ravi Palurif4b38e72020-02-05 12:35:41 +0530203 private static final int MSG_EXPLICIT_CALL_TRANSFER = 40;
204 private static final int MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE = 41;
Grace Jia4e8dc102021-01-19 14:58:01 -0800205 private static final int MSG_ON_CALL_FILTERING_COMPLETED = 42;
206 private static final int MSG_ON_USING_ALTERNATIVE_UI = 43;
207 private static final int MSG_ON_TRACKED_BY_NON_UI_SERVICE = 44;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700208
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700209 private static Connection sNullConnection;
210
mike dooley95e80702014-09-18 14:07:52 -0700211 private final Map<String, Connection> mConnectionById = new ConcurrentHashMap<>();
212 private final Map<Connection, String> mIdByConnection = new ConcurrentHashMap<>();
213 private final Map<String, Conference> mConferenceById = new ConcurrentHashMap<>();
214 private final Map<Conference, String> mIdByConference = new ConcurrentHashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700215 private final RemoteConnectionManager mRemoteConnectionManager =
216 new RemoteConnectionManager(this);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700217 private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700218 private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
Ihab Awad542e0ea2014-05-16 10:22:16 -0700219
Santos Cordon823fd3c2014-08-07 18:35:18 -0700220 private boolean mAreAccountsInitialized = false;
Santos Cordon0159ac02014-08-21 14:28:11 -0700221 private Conference sNullConference;
Tyler Gunnf0500bd2015-09-01 10:59:48 -0700222 private Object mIdSyncRoot = new Object();
223 private int mId = 0;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700224
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700225 private final IBinder mBinder = new IConnectionService.Stub() {
226 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700227 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
228 Session.Info sessionInfo) {
229 Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
230 try {
231 SomeArgs args = SomeArgs.obtain();
232 args.arg1 = adapter;
233 args.arg2 = Log.createSubsession();
234 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
235 } finally {
236 Log.endSession();
237 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700238 }
239
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700240 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
241 Session.Info sessionInfo) {
242 Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
243 try {
244 SomeArgs args = SomeArgs.obtain();
245 args.arg1 = adapter;
246 args.arg2 = Log.createSubsession();
247 mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
248 } finally {
249 Log.endSession();
250 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700251 }
252
253 @Override
Ihab Awadf8b69882014-07-25 15:14:01 -0700254 public void createConnection(
255 PhoneAccountHandle connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700256 String id,
Ihab Awadf8b69882014-07-25 15:14:01 -0700257 ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700258 boolean isIncoming,
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700259 boolean isUnknown,
260 Session.Info sessionInfo) {
261 Log.startSession(sessionInfo, SESSION_CREATE_CONN);
262 try {
263 SomeArgs args = SomeArgs.obtain();
264 args.arg1 = connectionManagerPhoneAccount;
265 args.arg2 = id;
266 args.arg3 = request;
267 args.arg4 = Log.createSubsession();
268 args.argi1 = isIncoming ? 1 : 0;
269 args.argi2 = isUnknown ? 1 : 0;
270 mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
271 } finally {
272 Log.endSession();
273 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700274 }
275
276 @Override
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700277 public void createConnectionComplete(String id, Session.Info sessionInfo) {
278 Log.startSession(sessionInfo, SESSION_CREATE_CONN_COMPLETE);
279 try {
280 SomeArgs args = SomeArgs.obtain();
281 args.arg1 = id;
282 args.arg2 = Log.createSubsession();
283 mHandler.obtainMessage(MSG_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
284 } finally {
285 Log.endSession();
286 }
287 }
288
289 @Override
Tyler Gunn44e01912017-01-31 10:49:05 -0800290 public void createConnectionFailed(
Tyler Gunn159f35c2017-03-02 09:28:37 -0800291 PhoneAccountHandle connectionManagerPhoneAccount,
Tyler Gunn44e01912017-01-31 10:49:05 -0800292 String callId,
293 ConnectionRequest request,
294 boolean isIncoming,
295 Session.Info sessionInfo) {
296 Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
297 try {
298 SomeArgs args = SomeArgs.obtain();
299 args.arg1 = callId;
300 args.arg2 = request;
301 args.arg3 = Log.createSubsession();
Tyler Gunn159f35c2017-03-02 09:28:37 -0800302 args.arg4 = connectionManagerPhoneAccount;
Tyler Gunn44e01912017-01-31 10:49:05 -0800303 args.argi1 = isIncoming ? 1 : 0;
304 mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
305 } finally {
306 Log.endSession();
307 }
308 }
309
310 @Override
Ravi Paluri80aa2142019-12-02 11:57:37 +0530311 public void createConference(
312 PhoneAccountHandle connectionManagerPhoneAccount,
313 String id,
314 ConnectionRequest request,
315 boolean isIncoming,
316 boolean isUnknown,
317 Session.Info sessionInfo) {
318 Log.startSession(sessionInfo, SESSION_CREATE_CONF);
319 try {
320 SomeArgs args = SomeArgs.obtain();
321 args.arg1 = connectionManagerPhoneAccount;
322 args.arg2 = id;
323 args.arg3 = request;
324 args.arg4 = Log.createSubsession();
325 args.argi1 = isIncoming ? 1 : 0;
326 args.argi2 = isUnknown ? 1 : 0;
327 mHandler.obtainMessage(MSG_CREATE_CONFERENCE, args).sendToTarget();
328 } finally {
329 Log.endSession();
330 }
331 }
332
333 @Override
334 public void createConferenceComplete(String id, Session.Info sessionInfo) {
335 Log.startSession(sessionInfo, SESSION_CREATE_CONF_COMPLETE);
336 try {
337 SomeArgs args = SomeArgs.obtain();
338 args.arg1 = id;
339 args.arg2 = Log.createSubsession();
340 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_COMPLETE, args).sendToTarget();
341 } finally {
342 Log.endSession();
343 }
344 }
345
346 @Override
347 public void createConferenceFailed(
348 PhoneAccountHandle connectionManagerPhoneAccount,
349 String callId,
350 ConnectionRequest request,
351 boolean isIncoming,
352 Session.Info sessionInfo) {
353 Log.startSession(sessionInfo, SESSION_CREATE_CONF_FAILED);
354 try {
355 SomeArgs args = SomeArgs.obtain();
356 args.arg1 = callId;
357 args.arg2 = request;
358 args.arg3 = Log.createSubsession();
359 args.arg4 = connectionManagerPhoneAccount;
360 args.argi1 = isIncoming ? 1 : 0;
361 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_FAILED, args).sendToTarget();
362 } finally {
363 Log.endSession();
364 }
365 }
366
367 @Override
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800368 public void handoverFailed(String callId, ConnectionRequest request, int reason,
369 Session.Info sessionInfo) {
370 Log.startSession(sessionInfo, SESSION_HANDOVER_FAILED);
371 try {
372 SomeArgs args = SomeArgs.obtain();
373 args.arg1 = callId;
374 args.arg2 = request;
375 args.arg3 = Log.createSubsession();
376 args.arg4 = reason;
377 mHandler.obtainMessage(MSG_HANDOVER_FAILED, args).sendToTarget();
378 } finally {
379 Log.endSession();
380 }
381 }
382
383 @Override
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800384 public void handoverComplete(String callId, Session.Info sessionInfo) {
385 Log.startSession(sessionInfo, SESSION_HANDOVER_COMPLETE);
386 try {
387 SomeArgs args = SomeArgs.obtain();
388 args.arg1 = callId;
389 args.arg2 = Log.createSubsession();
390 mHandler.obtainMessage(MSG_HANDOVER_COMPLETE, args).sendToTarget();
391 } finally {
392 Log.endSession();
393 }
394 }
395
396 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700397 public void abort(String callId, Session.Info sessionInfo) {
398 Log.startSession(sessionInfo, SESSION_ABORT);
399 try {
400 SomeArgs args = SomeArgs.obtain();
401 args.arg1 = callId;
402 args.arg2 = Log.createSubsession();
403 mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
404 } finally {
405 Log.endSession();
406 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700407 }
408
409 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700410 public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
411 Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
412 try {
413 SomeArgs args = SomeArgs.obtain();
414 args.arg1 = callId;
415 args.arg2 = Log.createSubsession();
416 args.argi1 = videoState;
417 mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
418 } finally {
419 Log.endSession();
420 }
Tyler Gunnbe74de02014-08-29 14:51:48 -0700421 }
422
423 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700424 public void answer(String callId, Session.Info sessionInfo) {
425 Log.startSession(sessionInfo, SESSION_ANSWER);
426 try {
427 SomeArgs args = SomeArgs.obtain();
428 args.arg1 = callId;
429 args.arg2 = Log.createSubsession();
430 mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
431 } finally {
432 Log.endSession();
433 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700434 }
435
436 @Override
Pooja Jaind34698d2017-12-28 14:15:31 +0530437 public void deflect(String callId, Uri address, Session.Info sessionInfo) {
438 Log.startSession(sessionInfo, SESSION_DEFLECT);
439 try {
440 SomeArgs args = SomeArgs.obtain();
441 args.arg1 = callId;
442 args.arg2 = address;
443 args.arg3 = Log.createSubsession();
444 mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
445 } finally {
446 Log.endSession();
447 }
448 }
449
450 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700451 public void reject(String callId, Session.Info sessionInfo) {
452 Log.startSession(sessionInfo, SESSION_REJECT);
453 try {
454 SomeArgs args = SomeArgs.obtain();
455 args.arg1 = callId;
456 args.arg2 = Log.createSubsession();
457 mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
458 } finally {
459 Log.endSession();
460 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700461 }
462
463 @Override
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800464 public void rejectWithReason(String callId,
465 @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
466 Log.startSession(sessionInfo, SESSION_REJECT);
467 try {
468 SomeArgs args = SomeArgs.obtain();
469 args.arg1 = callId;
470 args.argi1 = rejectReason;
471 args.arg2 = Log.createSubsession();
472 mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
473 } finally {
474 Log.endSession();
475 }
476 }
477
478 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700479 public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
480 Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
481 try {
482 SomeArgs args = SomeArgs.obtain();
483 args.arg1 = callId;
484 args.arg2 = message;
485 args.arg3 = Log.createSubsession();
486 mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
487 } finally {
488 Log.endSession();
489 }
Bryce Lee81901682015-08-28 16:38:02 -0700490 }
491
492 @Override
Ravi Palurif4b38e72020-02-05 12:35:41 +0530493 public void transfer(@NonNull String callId, @NonNull Uri number,
494 boolean isConfirmationRequired, Session.Info sessionInfo) {
495 Log.startSession(sessionInfo, SESSION_TRANSFER);
496 try {
497 SomeArgs args = SomeArgs.obtain();
498 args.arg1 = callId;
499 args.arg2 = number;
500 args.argi1 = isConfirmationRequired ? 1 : 0;
501 args.arg3 = Log.createSubsession();
502 mHandler.obtainMessage(MSG_EXPLICIT_CALL_TRANSFER, args).sendToTarget();
503 } finally {
504 Log.endSession();
505 }
506 }
507
508 @Override
509 public void consultativeTransfer(@NonNull String callId, @NonNull String otherCallId,
510 Session.Info sessionInfo) {
511 Log.startSession(sessionInfo, SESSION_CONSULTATIVE_TRANSFER);
512 try {
513 SomeArgs args = SomeArgs.obtain();
514 args.arg1 = callId;
515 args.arg2 = otherCallId;
516 args.arg3 = Log.createSubsession();
517 mHandler.obtainMessage(
518 MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE, args).sendToTarget();
519 } finally {
520 Log.endSession();
521 }
522 }
523
524 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700525 public void silence(String callId, Session.Info sessionInfo) {
526 Log.startSession(sessionInfo, SESSION_SILENCE);
527 try {
528 SomeArgs args = SomeArgs.obtain();
529 args.arg1 = callId;
530 args.arg2 = Log.createSubsession();
531 mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
532 } finally {
533 Log.endSession();
534 }
Bryce Leecac50772015-11-17 15:13:29 -0800535 }
536
537 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700538 public void disconnect(String callId, Session.Info sessionInfo) {
539 Log.startSession(sessionInfo, SESSION_DISCONNECT);
540 try {
541 SomeArgs args = SomeArgs.obtain();
542 args.arg1 = callId;
543 args.arg2 = Log.createSubsession();
544 mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
545 } finally {
546 Log.endSession();
547 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700548 }
549
550 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700551 public void hold(String callId, Session.Info sessionInfo) {
552 Log.startSession(sessionInfo, SESSION_HOLD);
553 try {
554 SomeArgs args = SomeArgs.obtain();
555 args.arg1 = callId;
556 args.arg2 = Log.createSubsession();
557 mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
558 } finally {
559 Log.endSession();
560 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700561 }
562
563 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700564 public void unhold(String callId, Session.Info sessionInfo) {
565 Log.startSession(sessionInfo, SESSION_UNHOLD);
566 try {
567 SomeArgs args = SomeArgs.obtain();
568 args.arg1 = callId;
569 args.arg2 = Log.createSubsession();
570 mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
571 } finally {
572 Log.endSession();
573 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700574 }
575
576 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700577 public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
578 Session.Info sessionInfo) {
579 Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
580 try {
581 SomeArgs args = SomeArgs.obtain();
582 args.arg1 = callId;
583 args.arg2 = callAudioState;
584 args.arg3 = Log.createSubsession();
585 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
586 } finally {
587 Log.endSession();
588 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700589 }
590
591 @Override
Grace Jia4e8dc102021-01-19 14:58:01 -0800592 public void onUsingAlternativeUi(String callId, boolean usingAlternativeUiShowing,
593 Session.Info sessionInfo) {
594 Log.startSession(sessionInfo, SESSION_USING_ALTERNATIVE_UI);
595 try {
596 SomeArgs args = SomeArgs.obtain();
597 args.arg1 = callId;
598 args.arg2 = usingAlternativeUiShowing;
599 args.arg3 = Log.createSubsession();
600 mHandler.obtainMessage(MSG_ON_USING_ALTERNATIVE_UI, args).sendToTarget();
601 } finally {
602 Log.endSession();
603 }
604 }
605
606 @Override
607 public void onTrackedByNonUiService(String callId, boolean isTracked,
608 Session.Info sessionInfo) {
609 Log.startSession(sessionInfo, SESSION_TRACKED_BY_NON_UI_SERVICE);
610 try {
611 SomeArgs args = SomeArgs.obtain();
612 args.arg1 = callId;
613 args.arg2 = isTracked;
614 args.arg3 = Log.createSubsession();
615 mHandler.obtainMessage(MSG_ON_TRACKED_BY_NON_UI_SERVICE, args).sendToTarget();
616 } finally {
617 Log.endSession();
618 }
619 }
620
621 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700622 public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
623 Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
624 try {
625 SomeArgs args = SomeArgs.obtain();
626 args.arg1 = digit;
627 args.arg2 = callId;
628 args.arg3 = Log.createSubsession();
629 mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, args).sendToTarget();
630 } finally {
631 Log.endSession();
632 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700633 }
634
635 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700636 public void stopDtmfTone(String callId, Session.Info sessionInfo) {
637 Log.startSession(sessionInfo, SESSION_STOP_DTMF);
638 try {
639 SomeArgs args = SomeArgs.obtain();
640 args.arg1 = callId;
641 args.arg2 = Log.createSubsession();
642 mHandler.obtainMessage(MSG_STOP_DTMF_TONE, args).sendToTarget();
643 } finally {
644 Log.endSession();
645 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700646 }
647
648 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700649 public void conference(String callId1, String callId2, Session.Info sessionInfo) {
650 Log.startSession(sessionInfo, SESSION_CONFERENCE);
651 try {
652 SomeArgs args = SomeArgs.obtain();
653 args.arg1 = callId1;
654 args.arg2 = callId2;
655 args.arg3 = Log.createSubsession();
656 mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
657 } finally {
658 Log.endSession();
659 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700660 }
661
662 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700663 public void splitFromConference(String callId, Session.Info sessionInfo) {
664 Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
665 try {
666 SomeArgs args = SomeArgs.obtain();
667 args.arg1 = callId;
668 args.arg2 = Log.createSubsession();
669 mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
670 } finally {
671 Log.endSession();
672 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700673 }
674
675 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700676 public void mergeConference(String callId, Session.Info sessionInfo) {
677 Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
678 try {
679 SomeArgs args = SomeArgs.obtain();
680 args.arg1 = callId;
681 args.arg2 = Log.createSubsession();
682 mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
683 } finally {
684 Log.endSession();
685 }
Santos Cordona4868042014-09-04 17:39:22 -0700686 }
687
688 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700689 public void swapConference(String callId, Session.Info sessionInfo) {
690 Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
691 try {
692 SomeArgs args = SomeArgs.obtain();
693 args.arg1 = callId;
694 args.arg2 = Log.createSubsession();
695 mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
696 } finally {
697 Log.endSession();
698 }
Santos Cordona4868042014-09-04 17:39:22 -0700699 }
700
701 @Override
Ravi Paluri404babb2020-01-23 19:02:44 +0530702 public void addConferenceParticipants(String callId, List<Uri> participants,
703 Session.Info sessionInfo) {
704 Log.startSession(sessionInfo, SESSION_ADD_PARTICIPANT);
705 try {
706 SomeArgs args = SomeArgs.obtain();
707 args.arg1 = callId;
708 args.arg2 = participants;
709 args.arg3 = Log.createSubsession();
710 mHandler.obtainMessage(MSG_ADD_PARTICIPANT, args).sendToTarget();
711 } finally {
712 Log.endSession();
713 }
714 }
715
716 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700717 public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
718 Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
719 try {
720 SomeArgs args = SomeArgs.obtain();
721 args.arg1 = callId;
722 args.arg2 = Log.createSubsession();
723 args.argi1 = proceed ? 1 : 0;
724 mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
725 } finally {
726 Log.endSession();
727 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700728 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700729
730 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700731 public void pullExternalCall(String callId, Session.Info sessionInfo) {
732 Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
733 try {
734 SomeArgs args = SomeArgs.obtain();
735 args.arg1 = callId;
736 args.arg2 = Log.createSubsession();
737 mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
738 } finally {
739 Log.endSession();
740 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700741 }
742
743 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700744 public void sendCallEvent(String callId, String event, Bundle extras,
745 Session.Info sessionInfo) {
746 Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
747 try {
748 SomeArgs args = SomeArgs.obtain();
749 args.arg1 = callId;
750 args.arg2 = event;
751 args.arg3 = extras;
752 args.arg4 = Log.createSubsession();
753 mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
754 } finally {
755 Log.endSession();
756 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700757 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700758
759 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700760 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
761 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
762 try {
763 SomeArgs args = SomeArgs.obtain();
764 args.arg1 = callId;
765 args.arg2 = extras;
766 args.arg3 = Log.createSubsession();
767 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
768 } finally {
769 Log.endSession();
770 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700771 }
Hall Liub64ac4c2017-02-06 10:49:48 -0800772
773 @Override
774 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
775 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
776 Log.startSession(sessionInfo, SESSION_START_RTT);
777 try {
778 SomeArgs args = SomeArgs.obtain();
779 args.arg1 = callId;
780 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
781 args.arg3 = Log.createSubsession();
782 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
783 } finally {
784 Log.endSession();
785 }
786 }
787
788 @Override
789 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
790 Log.startSession(sessionInfo, SESSION_STOP_RTT);
791 try {
792 SomeArgs args = SomeArgs.obtain();
793 args.arg1 = callId;
794 args.arg2 = Log.createSubsession();
795 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
796 } finally {
797 Log.endSession();
798 }
799 }
800
801 @Override
802 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
803 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
804 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
805 try {
806 SomeArgs args = SomeArgs.obtain();
807 args.arg1 = callId;
808 if (toInCall == null || fromInCall == null) {
809 args.arg2 = null;
810 } else {
811 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
812 }
813 args.arg3 = Log.createSubsession();
814 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
815 } finally {
816 Log.endSession();
817 }
818 }
Pengquan Meng731c1a32017-11-21 18:01:13 -0800819
820 @Override
821 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
822 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
823 try {
824 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
825 } finally {
826 Log.endSession();
827 }
828 }
829
830 @Override
831 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
832 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
833 try {
834 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
835 } finally {
836 Log.endSession();
837 }
838 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700839 };
840
841 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
842 @Override
843 public void handleMessage(Message msg) {
844 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700845 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
846 SomeArgs args = (SomeArgs) msg.obj;
847 try {
848 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
849 Log.continueSession((Session) args.arg2,
850 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
851 mAdapter.addAdapter(adapter);
852 onAdapterAttached();
853 } finally {
854 args.recycle();
855 Log.endSession();
856 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700857 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700858 }
859 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
860 SomeArgs args = (SomeArgs) msg.obj;
861 try {
862 Log.continueSession((Session) args.arg2,
863 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
864 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
865 } finally {
866 args.recycle();
867 Log.endSession();
868 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700869 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700870 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700871 case MSG_CREATE_CONNECTION: {
872 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700873 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -0700874 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700875 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -0700876 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700877 final String id = (String) args.arg2;
878 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700879 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -0700880 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700881 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700882 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700883 mPreInitializationConnectionRequests.add(
884 new android.telecom.Logging.Runnable(
885 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
886 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700887 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700888 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700889 createConnection(
890 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700891 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700892 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700893 isIncoming,
894 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700895 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700896 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -0700897 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700898 createConnection(
899 connectionManagerPhoneAccount,
900 id,
901 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700902 isIncoming,
903 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700904 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700905 } finally {
906 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700907 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -0700908 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700909 break;
Ihab Awadf8b69882014-07-25 15:14:01 -0700910 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700911 case MSG_CREATE_CONNECTION_COMPLETE: {
912 SomeArgs args = (SomeArgs) msg.obj;
913 Log.continueSession((Session) args.arg2,
914 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
915 try {
916 final String id = (String) args.arg1;
917 if (!mAreAccountsInitialized) {
918 Log.d(this, "Enqueueing pre-init request %s", id);
919 mPreInitializationConnectionRequests.add(
920 new android.telecom.Logging.Runnable(
921 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
922 + ".pICR",
923 null /*lock*/) {
924 @Override
925 public void loggedRun() {
926 notifyCreateConnectionComplete(id);
927 }
928 }.prepare());
929 } else {
930 notifyCreateConnectionComplete(id);
931 }
932 } finally {
933 args.recycle();
934 Log.endSession();
935 }
936 break;
937 }
Tyler Gunn44e01912017-01-31 10:49:05 -0800938 case MSG_CREATE_CONNECTION_FAILED: {
939 SomeArgs args = (SomeArgs) msg.obj;
940 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
941 SESSION_CREATE_CONN_FAILED);
942 try {
943 final String id = (String) args.arg1;
944 final ConnectionRequest request = (ConnectionRequest) args.arg2;
945 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800946 final PhoneAccountHandle connectionMgrPhoneAccount =
947 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -0800948 if (!mAreAccountsInitialized) {
949 Log.d(this, "Enqueueing pre-init request %s", id);
950 mPreInitializationConnectionRequests.add(
951 new android.telecom.Logging.Runnable(
952 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
953 null /*lock*/) {
954 @Override
955 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800956 createConnectionFailed(connectionMgrPhoneAccount, id,
957 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800958 }
959 }.prepare());
960 } else {
961 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -0800962 createConnectionFailed(connectionMgrPhoneAccount, id, request,
963 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800964 }
965 } finally {
966 args.recycle();
967 Log.endSession();
968 }
969 break;
970 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530971 case MSG_CREATE_CONFERENCE: {
972 SomeArgs args = (SomeArgs) msg.obj;
973 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
974 try {
975 final PhoneAccountHandle connectionManagerPhoneAccount =
976 (PhoneAccountHandle) args.arg1;
977 final String id = (String) args.arg2;
978 final ConnectionRequest request = (ConnectionRequest) args.arg3;
979 final boolean isIncoming = args.argi1 == 1;
980 final boolean isUnknown = args.argi2 == 1;
981 if (!mAreAccountsInitialized) {
982 Log.d(this, "Enqueueing pre-initconference request %s", id);
983 mPreInitializationConnectionRequests.add(
984 new android.telecom.Logging.Runnable(
985 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
986 null /*lock*/) {
987 @Override
988 public void loggedRun() {
989 createConference(connectionManagerPhoneAccount,
990 id,
991 request,
992 isIncoming,
993 isUnknown);
994 }
995 }.prepare());
996 } else {
997 createConference(connectionManagerPhoneAccount,
998 id,
999 request,
1000 isIncoming,
1001 isUnknown);
1002 }
1003 } finally {
1004 args.recycle();
1005 Log.endSession();
1006 }
1007 break;
1008 }
1009 case MSG_CREATE_CONFERENCE_COMPLETE: {
1010 SomeArgs args = (SomeArgs) msg.obj;
1011 Log.continueSession((Session) args.arg2,
1012 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1013 try {
1014 final String id = (String) args.arg1;
1015 if (!mAreAccountsInitialized) {
1016 Log.d(this, "Enqueueing pre-init conference request %s", id);
1017 mPreInitializationConnectionRequests.add(
1018 new android.telecom.Logging.Runnable(
1019 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
1020 + ".pIConfR",
1021 null /*lock*/) {
1022 @Override
1023 public void loggedRun() {
1024 notifyCreateConferenceComplete(id);
1025 }
1026 }.prepare());
1027 } else {
1028 notifyCreateConferenceComplete(id);
1029 }
1030 } finally {
1031 args.recycle();
1032 Log.endSession();
1033 }
1034 break;
1035 }
1036 case MSG_CREATE_CONFERENCE_FAILED: {
1037 SomeArgs args = (SomeArgs) msg.obj;
1038 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1039 SESSION_CREATE_CONN_FAILED);
1040 try {
1041 final String id = (String) args.arg1;
1042 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1043 final boolean isIncoming = args.argi1 == 1;
1044 final PhoneAccountHandle connectionMgrPhoneAccount =
1045 (PhoneAccountHandle) args.arg4;
1046 if (!mAreAccountsInitialized) {
1047 Log.d(this, "Enqueueing pre-init conference request %s", id);
1048 mPreInitializationConnectionRequests.add(
1049 new android.telecom.Logging.Runnable(
1050 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
1051 + ".pIConfR",
1052 null /*lock*/) {
1053 @Override
1054 public void loggedRun() {
1055 createConferenceFailed(connectionMgrPhoneAccount, id,
1056 request, isIncoming);
1057 }
1058 }.prepare());
1059 } else {
1060 Log.i(this, "createConferenceFailed %s", id);
1061 createConferenceFailed(connectionMgrPhoneAccount, id, request,
1062 isIncoming);
1063 }
1064 } finally {
1065 args.recycle();
1066 Log.endSession();
1067 }
1068 break;
1069 }
1070
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001071 case MSG_HANDOVER_FAILED: {
1072 SomeArgs args = (SomeArgs) msg.obj;
1073 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1074 SESSION_HANDOVER_FAILED);
1075 try {
1076 final String id = (String) args.arg1;
1077 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1078 final int reason = (int) args.arg4;
1079 if (!mAreAccountsInitialized) {
1080 Log.d(this, "Enqueueing pre-init request %s", id);
1081 mPreInitializationConnectionRequests.add(
1082 new android.telecom.Logging.Runnable(
1083 SESSION_HANDLER
1084 + SESSION_HANDOVER_FAILED + ".pICR",
1085 null /*lock*/) {
1086 @Override
1087 public void loggedRun() {
1088 handoverFailed(id, request, reason);
1089 }
1090 }.prepare());
1091 } else {
1092 Log.i(this, "createConnectionFailed %s", id);
1093 handoverFailed(id, request, reason);
1094 }
1095 } finally {
1096 args.recycle();
1097 Log.endSession();
1098 }
1099 break;
1100 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001101 case MSG_ABORT: {
1102 SomeArgs args = (SomeArgs) msg.obj;
1103 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1104 try {
1105 abort((String) args.arg1);
1106 } finally {
1107 args.recycle();
1108 Log.endSession();
1109 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001110 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001111 }
1112 case MSG_ANSWER: {
1113 SomeArgs args = (SomeArgs) msg.obj;
1114 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1115 try {
1116 answer((String) args.arg1);
1117 } finally {
1118 args.recycle();
1119 Log.endSession();
1120 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001121 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001122 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001123 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001124 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001125 Log.continueSession((Session) args.arg2,
1126 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001127 try {
1128 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001129 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001130 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001131 } finally {
1132 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001133 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001134 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001135 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001136 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301137 case MSG_DEFLECT: {
1138 SomeArgs args = (SomeArgs) msg.obj;
1139 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1140 try {
1141 deflect((String) args.arg1, (Uri) args.arg2);
1142 } finally {
1143 args.recycle();
1144 Log.endSession();
1145 }
1146 break;
1147 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001148 case MSG_REJECT: {
1149 SomeArgs args = (SomeArgs) msg.obj;
1150 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1151 try {
1152 reject((String) args.arg1);
1153 } finally {
1154 args.recycle();
1155 Log.endSession();
1156 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001157 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001158 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001159 case MSG_REJECT_WITH_REASON: {
1160 SomeArgs args = (SomeArgs) msg.obj;
1161 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1162 try {
1163 reject((String) args.arg1, args.argi1);
1164 } finally {
1165 args.recycle();
1166 Log.endSession();
1167 }
1168 break;
1169 }
Bryce Lee81901682015-08-28 16:38:02 -07001170 case MSG_REJECT_WITH_MESSAGE: {
1171 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001172 Log.continueSession((Session) args.arg3,
1173 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001174 try {
1175 reject((String) args.arg1, (String) args.arg2);
1176 } finally {
1177 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001178 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001179 }
1180 break;
1181 }
Ravi Palurif4b38e72020-02-05 12:35:41 +05301182 case MSG_EXPLICIT_CALL_TRANSFER: {
1183 SomeArgs args = (SomeArgs) msg.obj;
1184 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_TRANSFER);
1185 try {
1186 final boolean isConfirmationRequired = args.argi1 == 1;
1187 transfer((String) args.arg1, (Uri) args.arg2, isConfirmationRequired);
1188 } finally {
1189 args.recycle();
1190 Log.endSession();
1191 }
1192 break;
1193 }
1194 case MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE: {
1195 SomeArgs args = (SomeArgs) msg.obj;
1196 Log.continueSession(
1197 (Session) args.arg3, SESSION_HANDLER + SESSION_CONSULTATIVE_TRANSFER);
1198 try {
1199 consultativeTransfer((String) args.arg1, (String) args.arg2);
1200 } finally {
1201 args.recycle();
1202 Log.endSession();
1203 }
1204 break;
1205 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001206 case MSG_DISCONNECT: {
1207 SomeArgs args = (SomeArgs) msg.obj;
1208 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1209 try {
1210 disconnect((String) args.arg1);
1211 } finally {
1212 args.recycle();
1213 Log.endSession();
1214 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001215 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001216 }
1217 case MSG_SILENCE: {
1218 SomeArgs args = (SomeArgs) msg.obj;
1219 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1220 try {
1221 silence((String) args.arg1);
1222 } finally {
1223 args.recycle();
1224 Log.endSession();
1225 }
Bryce Leecac50772015-11-17 15:13:29 -08001226 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001227 }
1228 case MSG_HOLD: {
1229 SomeArgs args = (SomeArgs) msg.obj;
1230 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1231 try {
1232 hold((String) args.arg1);
1233 } finally {
1234 args.recycle();
1235 Log.endSession();
1236 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001237 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001238 }
1239 case MSG_UNHOLD: {
1240 SomeArgs args = (SomeArgs) msg.obj;
1241 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1242 try {
1243 unhold((String) args.arg1);
1244 } finally {
1245 args.recycle();
1246 Log.endSession();
1247 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001248 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001249 }
Yorke Lee4af59352015-05-13 14:14:54 -07001250 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001251 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001252 Log.continueSession((Session) args.arg3,
1253 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001254 try {
1255 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001256 CallAudioState audioState = (CallAudioState) args.arg2;
1257 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001258 } finally {
1259 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001260 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001261 }
1262 break;
1263 }
Grace Jia4e8dc102021-01-19 14:58:01 -08001264 case MSG_ON_USING_ALTERNATIVE_UI: {
1265 SomeArgs args = (SomeArgs) msg.obj;
1266 Log.continueSession((Session) args.arg3,
1267 SESSION_HANDLER + SESSION_USING_ALTERNATIVE_UI);
1268 try {
1269 String callId = (String) args.arg1;
1270 boolean isUsingAlternativeUi = (boolean) args.arg2;
1271 onUsingAlternativeUi(callId, isUsingAlternativeUi);
1272 } finally {
1273 args.recycle();
1274 Log.endSession();
1275 }
1276 break;
1277 }
1278 case MSG_ON_TRACKED_BY_NON_UI_SERVICE: {
1279 SomeArgs args = (SomeArgs) msg.obj;
1280 Log.continueSession((Session) args.arg3,
1281 SESSION_HANDLER + SESSION_TRACKED_BY_NON_UI_SERVICE);
1282 try {
1283 String callId = (String) args.arg1;
1284 boolean isTracked = (boolean) args.arg2;
1285 onTrackedByNonUiService(callId, isTracked);
1286 } finally {
1287 args.recycle();
1288 Log.endSession();
1289 }
1290 break;
1291 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001292 case MSG_PLAY_DTMF_TONE: {
1293 SomeArgs args = (SomeArgs) msg.obj;
1294 try {
1295 Log.continueSession((Session) args.arg3,
1296 SESSION_HANDLER + SESSION_PLAY_DTMF);
1297 playDtmfTone((String) args.arg2, (char) args.arg1);
1298 } finally {
1299 args.recycle();
1300 Log.endSession();
1301 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001302 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001303 }
1304 case MSG_STOP_DTMF_TONE: {
1305 SomeArgs args = (SomeArgs) msg.obj;
1306 try {
1307 Log.continueSession((Session) args.arg2,
1308 SESSION_HANDLER + SESSION_STOP_DTMF);
1309 stopDtmfTone((String) args.arg1);
1310 } finally {
1311 args.recycle();
1312 Log.endSession();
1313 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001314 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001315 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001316 case MSG_CONFERENCE: {
1317 SomeArgs args = (SomeArgs) msg.obj;
1318 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001319 Log.continueSession((Session) args.arg3,
1320 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001321 String callId1 = (String) args.arg1;
1322 String callId2 = (String) args.arg2;
1323 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001324 } finally {
1325 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001326 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001327 }
1328 break;
1329 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001330 case MSG_SPLIT_FROM_CONFERENCE: {
1331 SomeArgs args = (SomeArgs) msg.obj;
1332 try {
1333 Log.continueSession((Session) args.arg2,
1334 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1335 splitFromConference((String) args.arg1);
1336 } finally {
1337 args.recycle();
1338 Log.endSession();
1339 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001340 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001341 }
1342 case MSG_MERGE_CONFERENCE: {
1343 SomeArgs args = (SomeArgs) msg.obj;
1344 try {
1345 Log.continueSession((Session) args.arg2,
1346 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1347 mergeConference((String) args.arg1);
1348 } finally {
1349 args.recycle();
1350 Log.endSession();
1351 }
Santos Cordona4868042014-09-04 17:39:22 -07001352 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001353 }
1354 case MSG_SWAP_CONFERENCE: {
1355 SomeArgs args = (SomeArgs) msg.obj;
1356 try {
1357 Log.continueSession((Session) args.arg2,
1358 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1359 swapConference((String) args.arg1);
1360 } finally {
1361 args.recycle();
1362 Log.endSession();
1363 }
Santos Cordona4868042014-09-04 17:39:22 -07001364 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001365 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301366 case MSG_ADD_PARTICIPANT: {
1367 SomeArgs args = (SomeArgs) msg.obj;
1368 try {
1369 Log.continueSession((Session) args.arg3,
1370 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1371 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1372 } finally {
1373 args.recycle();
1374 Log.endSession();
1375 }
1376 break;
1377 }
1378
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001379 case MSG_ON_POST_DIAL_CONTINUE: {
1380 SomeArgs args = (SomeArgs) msg.obj;
1381 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001382 Log.continueSession((Session) args.arg2,
1383 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001384 String callId = (String) args.arg1;
1385 boolean proceed = (args.argi1 == 1);
1386 onPostDialContinue(callId, proceed);
1387 } finally {
1388 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001389 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001390 }
1391 break;
1392 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001393 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001394 SomeArgs args = (SomeArgs) msg.obj;
1395 try {
1396 Log.continueSession((Session) args.arg2,
1397 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1398 pullExternalCall((String) args.arg1);
1399 } finally {
1400 args.recycle();
1401 Log.endSession();
1402 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001403 break;
1404 }
1405 case MSG_SEND_CALL_EVENT: {
1406 SomeArgs args = (SomeArgs) msg.obj;
1407 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001408 Log.continueSession((Session) args.arg4,
1409 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001410 String callId = (String) args.arg1;
1411 String event = (String) args.arg2;
1412 Bundle extras = (Bundle) args.arg3;
1413 sendCallEvent(callId, event, extras);
1414 } finally {
1415 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001416 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001417 }
1418 break;
1419 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001420 case MSG_HANDOVER_COMPLETE: {
1421 SomeArgs args = (SomeArgs) msg.obj;
1422 try {
1423 Log.continueSession((Session) args.arg2,
1424 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1425 String callId = (String) args.arg1;
1426 notifyHandoverComplete(callId);
1427 } finally {
1428 args.recycle();
1429 Log.endSession();
1430 }
1431 break;
1432 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001433 case MSG_ON_EXTRAS_CHANGED: {
1434 SomeArgs args = (SomeArgs) msg.obj;
1435 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001436 Log.continueSession((Session) args.arg3,
1437 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001438 String callId = (String) args.arg1;
1439 Bundle extras = (Bundle) args.arg2;
1440 handleExtrasChanged(callId, extras);
1441 } finally {
1442 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001443 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001444 }
1445 break;
1446 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001447 case MSG_ON_START_RTT: {
1448 SomeArgs args = (SomeArgs) msg.obj;
1449 try {
1450 Log.continueSession((Session) args.arg3,
1451 SESSION_HANDLER + SESSION_START_RTT);
1452 String callId = (String) args.arg1;
1453 Connection.RttTextStream rttTextStream =
1454 (Connection.RttTextStream) args.arg2;
1455 startRtt(callId, rttTextStream);
1456 } finally {
1457 args.recycle();
1458 Log.endSession();
1459 }
1460 break;
1461 }
1462 case MSG_ON_STOP_RTT: {
1463 SomeArgs args = (SomeArgs) msg.obj;
1464 try {
1465 Log.continueSession((Session) args.arg2,
1466 SESSION_HANDLER + SESSION_STOP_RTT);
1467 String callId = (String) args.arg1;
1468 stopRtt(callId);
1469 } finally {
1470 args.recycle();
1471 Log.endSession();
1472 }
1473 break;
1474 }
1475 case MSG_RTT_UPGRADE_RESPONSE: {
1476 SomeArgs args = (SomeArgs) msg.obj;
1477 try {
1478 Log.continueSession((Session) args.arg3,
1479 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1480 String callId = (String) args.arg1;
1481 Connection.RttTextStream rttTextStream =
1482 (Connection.RttTextStream) args.arg2;
1483 handleRttUpgradeResponse(callId, rttTextStream);
1484 } finally {
1485 args.recycle();
1486 Log.endSession();
1487 }
1488 break;
1489 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001490 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1491 onConnectionServiceFocusGained();
1492 break;
1493 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1494 onConnectionServiceFocusLost();
1495 break;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001496 default:
1497 break;
1498 }
1499 }
1500 };
1501
Santos Cordon823fd3c2014-08-07 18:35:18 -07001502 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1503 @Override
1504 public void onStateChanged(Conference conference, int oldState, int newState) {
1505 String id = mIdByConference.get(conference);
1506 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301507 case Connection.STATE_RINGING:
1508 mAdapter.setRinging(id);
1509 break;
1510 case Connection.STATE_DIALING:
1511 mAdapter.setDialing(id);
1512 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001513 case Connection.STATE_ACTIVE:
1514 mAdapter.setActive(id);
1515 break;
1516 case Connection.STATE_HOLDING:
1517 mAdapter.setOnHold(id);
1518 break;
1519 case Connection.STATE_DISCONNECTED:
1520 // handled by onDisconnected
1521 break;
1522 }
1523 }
1524
1525 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001526 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001527 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001528 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001529 }
1530
1531 @Override
1532 public void onConnectionAdded(Conference conference, Connection connection) {
1533 }
1534
1535 @Override
1536 public void onConnectionRemoved(Conference conference, Connection connection) {
1537 }
1538
1539 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001540 public void onConferenceableConnectionsChanged(
1541 Conference conference, List<Connection> conferenceableConnections) {
1542 mAdapter.setConferenceableConnections(
1543 mIdByConference.get(conference),
1544 createConnectionIdList(conferenceableConnections));
1545 }
1546
1547 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001548 public void onDestroyed(Conference conference) {
1549 removeConference(conference);
1550 }
1551
1552 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001553 public void onConnectionCapabilitiesChanged(
1554 Conference conference,
1555 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001556 String id = mIdByConference.get(conference);
1557 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001558 Connection.capabilitiesToString(connectionCapabilities));
1559 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001560 }
Rekha Kumar07366812015-03-24 16:42:31 -07001561
1562 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001563 public void onConnectionPropertiesChanged(
1564 Conference conference,
1565 int connectionProperties) {
1566 String id = mIdByConference.get(conference);
1567 Log.d(this, "call capabilities: conference: %s",
1568 Connection.propertiesToString(connectionProperties));
1569 mAdapter.setConnectionProperties(id, connectionProperties);
1570 }
1571
1572 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001573 public void onVideoStateChanged(Conference c, int videoState) {
1574 String id = mIdByConference.get(c);
1575 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1576 mAdapter.setVideoState(id, videoState);
1577 }
1578
1579 @Override
1580 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1581 String id = mIdByConference.get(c);
1582 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1583 videoProvider);
1584 mAdapter.setVideoProvider(id, videoProvider);
1585 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001586
1587 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001588 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1589 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001590 if (id != null) {
1591 mAdapter.setStatusHints(id, statusHints);
1592 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001593 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001594
1595 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001596 public void onExtrasChanged(Conference c, Bundle extras) {
1597 String id = mIdByConference.get(c);
1598 if (id != null) {
1599 mAdapter.putExtras(id, extras);
1600 }
1601 }
1602
1603 @Override
1604 public void onExtrasRemoved(Conference c, List<String> keys) {
1605 String id = mIdByConference.get(c);
1606 if (id != null) {
1607 mAdapter.removeExtras(id, keys);
1608 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001609 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001610
1611 @Override
1612 public void onConferenceStateChanged(Conference c, boolean isConference) {
1613 String id = mIdByConference.get(c);
1614 if (id != null) {
1615 mAdapter.setConferenceState(id, isConference);
1616 }
1617 }
1618
1619 @Override
Brad Ebingere0c12f42020-04-08 16:25:12 -07001620 public void onCallDirectionChanged(Conference c, int direction) {
1621 String id = mIdByConference.get(c);
1622 if (id != null) {
1623 mAdapter.setCallDirection(id, direction);
1624 }
1625 }
1626
1627 @Override
Tyler Gunn68a73a42018-10-03 15:38:57 -07001628 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1629 String id = mIdByConference.get(c);
1630 if (id != null) {
1631 mAdapter.setAddress(id, newAddress, presentation);
1632 }
1633 }
1634
1635 @Override
1636 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1637 int presentation) {
1638 String id = mIdByConference.get(c);
1639 if (id != null) {
1640 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1641 }
1642 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001643
1644 @Override
1645 public void onConnectionEvent(Conference c, String event, Bundle extras) {
1646 String id = mIdByConference.get(c);
1647 if (id != null) {
1648 mAdapter.onConnectionEvent(id, event, extras);
1649 }
1650 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301651
1652 @Override
1653 public void onRingbackRequested(Conference c, boolean ringback) {
1654 String id = mIdByConference.get(c);
1655 Log.d(this, "Adapter conference onRingback %b", ringback);
1656 mAdapter.setRingbackRequested(id, ringback);
1657 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001658 };
1659
Ihab Awad542e0ea2014-05-16 10:22:16 -07001660 private final Connection.Listener mConnectionListener = new Connection.Listener() {
1661 @Override
1662 public void onStateChanged(Connection c, int state) {
1663 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07001664 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001665 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001666 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001667 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001668 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001669 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001670 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001671 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001672 case Connection.STATE_PULLING_CALL:
1673 mAdapter.setPulling(id);
1674 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001675 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001676 // Handled in onDisconnected()
1677 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001678 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001679 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001680 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001681 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001682 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07001683 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001684 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001685 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001686 break;
1687 }
1688 }
1689
1690 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001691 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07001692 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07001693 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001694 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001695 }
1696
1697 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07001698 public void onVideoStateChanged(Connection c, int videoState) {
1699 String id = mIdByConnection.get(c);
1700 Log.d(this, "Adapter set video state %d", videoState);
1701 mAdapter.setVideoState(id, videoState);
1702 }
1703
1704 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001705 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001706 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001707 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07001708 }
1709
1710 @Override
1711 public void onCallerDisplayNameChanged(
1712 Connection c, String callerDisplayName, int presentation) {
1713 String id = mIdByConnection.get(c);
1714 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001715 }
1716
1717 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07001718 public void onDestroyed(Connection c) {
1719 removeConnection(c);
1720 }
Ihab Awadf8358972014-05-28 16:46:42 -07001721
1722 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001723 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07001724 String id = mIdByConnection.get(c);
1725 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001726 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001727 }
1728
1729 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001730 public void onPostDialChar(Connection c, char nextChar) {
1731 String id = mIdByConnection.get(c);
1732 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
1733 mAdapter.onPostDialChar(id, nextChar);
1734 }
1735
1736 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001737 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07001738 String id = mIdByConnection.get(c);
1739 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07001740 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07001741 }
Santos Cordonb6939982014-06-04 20:20:58 -07001742
1743 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001744 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07001745 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001746 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001747 Connection.capabilitiesToString(capabilities));
1748 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07001749 }
1750
Santos Cordonb6939982014-06-04 20:20:58 -07001751 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001752 public void onConnectionPropertiesChanged(Connection c, int properties) {
1753 String id = mIdByConnection.get(c);
1754 Log.d(this, "properties: parcelableconnection: %s",
1755 Connection.propertiesToString(properties));
1756 mAdapter.setConnectionProperties(id, properties);
1757 }
1758
1759 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001760 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001761 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07001762 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1763 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001764 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001765 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001766
1767 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001768 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001769 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001770 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001771 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001772
1773 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001774 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001775 String id = mIdByConnection.get(c);
1776 mAdapter.setStatusHints(id, statusHints);
1777 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001778
1779 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001780 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001781 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001782 mAdapter.setConferenceableConnections(
1783 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001784 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001785 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001786
1787 @Override
1788 public void onConferenceChanged(Connection connection, Conference conference) {
1789 String id = mIdByConnection.get(connection);
1790 if (id != null) {
1791 String conferenceId = null;
1792 if (conference != null) {
1793 conferenceId = mIdByConference.get(conference);
1794 }
1795 mAdapter.setIsConferenced(id, conferenceId);
1796 }
1797 }
Anthony Lee17455a32015-04-24 15:25:29 -07001798
1799 @Override
1800 public void onConferenceMergeFailed(Connection connection) {
1801 String id = mIdByConnection.get(connection);
1802 if (id != null) {
1803 mAdapter.onConferenceMergeFailed(id);
1804 }
1805 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001806
1807 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001808 public void onExtrasChanged(Connection c, Bundle extras) {
1809 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001810 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07001811 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001812 }
1813 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001814
Tyler Gunnf5035432017-01-09 09:43:12 -08001815 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001816 public void onExtrasRemoved(Connection c, List<String> keys) {
1817 String id = mIdByConnection.get(c);
1818 if (id != null) {
1819 mAdapter.removeExtras(id, keys);
1820 }
1821 }
1822
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001823 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001824 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001825 String id = mIdByConnection.get(connection);
1826 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001827 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001828 }
1829 }
Tyler Gunnf5035432017-01-09 09:43:12 -08001830
1831 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08001832 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001833 String id = mIdByConnection.get(c);
1834 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08001835 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08001836 }
1837 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001838
1839 @Override
1840 public void onRttInitiationSuccess(Connection c) {
1841 String id = mIdByConnection.get(c);
1842 if (id != null) {
1843 mAdapter.onRttInitiationSuccess(id);
1844 }
1845 }
1846
1847 @Override
1848 public void onRttInitiationFailure(Connection c, int reason) {
1849 String id = mIdByConnection.get(c);
1850 if (id != null) {
1851 mAdapter.onRttInitiationFailure(id, reason);
1852 }
1853 }
1854
1855 @Override
1856 public void onRttSessionRemotelyTerminated(Connection c) {
1857 String id = mIdByConnection.get(c);
1858 if (id != null) {
1859 mAdapter.onRttSessionRemotelyTerminated(id);
1860 }
1861 }
1862
1863 @Override
1864 public void onRemoteRttRequest(Connection c) {
1865 String id = mIdByConnection.get(c);
1866 if (id != null) {
1867 mAdapter.onRemoteRttRequest(id);
1868 }
1869 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05301870
1871 @Override
1872 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
1873 String id = mIdByConnection.get(c);
1874 if (id != null) {
1875 mAdapter.onPhoneAccountChanged(id, pHandle);
1876 }
1877 }
Mengjun Leng25707742017-07-04 11:10:37 +08001878
1879 public void onConnectionTimeReset(Connection c) {
1880 String id = mIdByConnection.get(c);
1881 if (id != null) {
1882 mAdapter.resetConnectionTime(id);
1883 }
1884 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001885 };
1886
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001887 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07001888 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001889 public final IBinder onBind(Intent intent) {
1890 return mBinder;
1891 }
1892
Santos Cordon29f2f2e2014-09-11 19:50:24 -07001893 /** {@inheritDoc} */
1894 @Override
1895 public boolean onUnbind(Intent intent) {
1896 endAllConnections();
1897 return super.onUnbind(intent);
1898 }
1899
Ravi Paluri80aa2142019-12-02 11:57:37 +05301900
1901 /**
1902 * This can be used by telecom to either create a new outgoing conference call or attach
1903 * to an existing incoming conference call. In either case, telecom will cycle through a
1904 * set of services and call createConference until a connection service cancels the process
1905 * or completes it successfully.
1906 */
1907 private void createConference(
1908 final PhoneAccountHandle callManagerAccount,
1909 final String callId,
1910 final ConnectionRequest request,
1911 boolean isIncoming,
1912 boolean isUnknown) {
1913
1914 Conference conference = null;
1915 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
1916 : onCreateOutgoingConference(callManagerAccount, request);
1917
1918 Log.d(this, "createConference, conference: %s", conference);
1919 if (conference == null) {
1920 Log.i(this, "createConference, implementation returned null conference.");
1921 conference = Conference.createFailedConference(
1922 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
1923 request.getAccountHandle());
1924 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001925
1926 Bundle extras = request.getExtras();
1927 Bundle newExtras = new Bundle();
1928 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
1929 if (extras != null) {
1930 // If the request originated from a remote connection service, we will add some
1931 // tracking information that Telecom can use to keep informed of which package
1932 // made the remote request, and which remote connection service was used.
1933 if (extras.containsKey(Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
1934 newExtras.putString(
1935 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
1936 extras.getString(
1937 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME));
1938 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
1939 request.getAccountHandle());
1940 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301941 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001942 conference.putExtras(newExtras);
1943
Ravi Paluri80aa2142019-12-02 11:57:37 +05301944 mConferenceById.put(callId, conference);
1945 mIdByConference.put(conference, callId);
Tyler Gunn460360d2020-07-29 10:21:45 -07001946
Ravi Paluri80aa2142019-12-02 11:57:37 +05301947 conference.addListener(mConferenceListener);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07001948 ParcelableConference parcelableConference = new ParcelableConference.Builder(
1949 request.getAccountHandle(), conference.getState())
1950 .setConnectionCapabilities(conference.getConnectionCapabilities())
1951 .setConnectionProperties(conference.getConnectionProperties())
1952 .setVideoAttributes(conference.getVideoProvider() == null
1953 ? null : conference.getVideoProvider().getInterface(),
1954 conference.getVideoState())
1955 .setConnectTimeMillis(conference.getConnectTimeMillis(),
1956 conference.getConnectionStartElapsedRealtimeMillis())
1957 .setStatusHints(conference.getStatusHints())
1958 .setExtras(conference.getExtras())
1959 .setAddress(conference.getAddress(), conference.getAddressPresentation())
1960 .setCallerDisplayName(conference.getCallerDisplayName(),
1961 conference.getCallerDisplayNamePresentation())
1962 .setDisconnectCause(conference.getDisconnectCause())
1963 .setRingbackRequested(conference.isRingbackRequested())
1964 .build();
Ravi Paluri80aa2142019-12-02 11:57:37 +05301965 if (conference.getState() != Connection.STATE_DISCONNECTED) {
1966 conference.setTelecomCallId(callId);
1967 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
1968 mAdapter.setVideoState(callId, conference.getVideoState());
1969 onConferenceAdded(conference);
1970 }
1971
1972 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
1973 mAdapter.handleCreateConferenceComplete(
1974 callId,
1975 request,
1976 parcelableConference);
1977 }
1978
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001979 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001980 * This can be used by telecom to either create a new outgoing call or attach to an existing
1981 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001982 * createConnection util a connection service cancels the process or completes it successfully.
1983 */
Ihab Awadf8b69882014-07-25 15:14:01 -07001984 private void createConnection(
1985 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001986 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07001987 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07001988 boolean isIncoming,
1989 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001990 boolean isLegacyHandover = request.getExtras() != null &&
1991 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
1992 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
1993 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Grace Jia4e8dc102021-01-19 14:58:01 -08001994 boolean addSelfManaged = request.getExtras() != null && request.getExtras().getBoolean(
Grace Jia8b22bb42021-02-02 15:37:32 -08001995 PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
Grace Jia4e8dc102021-01-19 14:58:01 -08001996 Log.i(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, "
1997 + "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b, "
1998 + " addSelfManaged: %b", callManagerAccount, callId, request, isIncoming,
1999 isUnknown, isLegacyHandover, isHandover, addSelfManaged);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002000
Sanket Padawee29a2662017-12-01 13:59:27 -08002001 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002002 if (isHandover) {
2003 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
2004 ? (PhoneAccountHandle) request.getExtras().getParcelable(
2005 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08002006 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002007 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002008 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002009 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002010 }
2011 } else {
2012 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
2013 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
2014 : onCreateOutgoingConnection(callManagerAccount, request);
2015 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002016 Log.d(this, "createConnection, connection: %s", connection);
2017 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002018 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002019 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002020 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002021 } else {
2022 try {
2023 Bundle extras = request.getExtras();
2024 if (extras != null) {
2025 // If the request originated from a remote connection service, we will add some
2026 // tracking information that Telecom can use to keep informed of which package
2027 // made the remote request, and which remote connection service was used.
2028 if (extras.containsKey(
2029 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2030 Bundle newExtras = new Bundle();
2031 newExtras.putString(
2032 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2033 extras.getString(
2034 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME
2035 ));
2036 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2037 request.getAccountHandle());
2038 connection.putExtras(newExtras);
2039 }
2040 }
2041 } catch (UnsupportedOperationException ose) {
2042 // Do nothing; if the ConnectionService reported a failure it will be an instance
2043 // of an immutable Connection which we cannot edit, so we're out of luck.
2044 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002045 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002046
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002047 boolean isSelfManaged =
2048 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
2049 == Connection.PROPERTY_SELF_MANAGED;
2050 // Self-managed Connections should always use voip audio mode; we default here so that the
2051 // local state within the ConnectionService matches the default we assume in Telecom.
2052 if (isSelfManaged) {
2053 connection.setAudioModeIsVoip(true);
2054 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002055 connection.setTelecomCallId(callId);
Sungjae7f4137452020-09-16 17:01:54 +09002056 PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
2057 ? request.getAccountHandle() : connection.getPhoneAccountHandle();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002058 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Sungjae7f4137452020-09-16 17:01:54 +09002059 addConnection(phoneAccountHandle, callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07002060 }
2061
Andrew Lee100e2932014-09-08 15:34:24 -07002062 Uri address = connection.getAddress();
2063 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07002064 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002065 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002066 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07002067 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
2068 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002069
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002070 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07002071 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002072 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07002073 request,
2074 new ParcelableConnection(
Sungjae7f4137452020-09-16 17:01:54 +09002075 phoneAccountHandle,
Evan Charltonbf11f982014-07-20 22:06:28 -07002076 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002077 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002078 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002079 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07002080 connection.getAddress(),
2081 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07002082 connection.getCallerDisplayName(),
2083 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002084 connection.getVideoProvider() == null ?
2085 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002086 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07002087 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002088 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002089 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002090 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07002091 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002092 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002093 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002094 connection.getExtras(),
2095 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08002096
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002097 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002098 // Tell ConnectionService to show its incoming call UX.
2099 connection.onShowIncomingCallUi();
2100 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002101 if (isUnknown) {
2102 triggerConferenceRecalculate();
2103 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002104 }
2105
Tyler Gunn159f35c2017-03-02 09:28:37 -08002106 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
2107 final String callId, final ConnectionRequest request,
2108 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08002109
2110 Log.i(this, "createConnectionFailed %s", callId);
2111 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002112 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002113 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002114 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002115 }
2116 }
2117
Ravi Paluri80aa2142019-12-02 11:57:37 +05302118 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
2119 final String callId, final ConnectionRequest request,
2120 boolean isIncoming) {
2121
2122 Log.i(this, "createConferenceFailed %s", callId);
2123 if (isIncoming) {
2124 onCreateIncomingConferenceFailed(callManagerAccount, request);
2125 } else {
2126 onCreateOutgoingConferenceFailed(callManagerAccount, request);
2127 }
2128 }
2129
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08002130 private void handoverFailed(final String callId, final ConnectionRequest request,
2131 int reason) {
2132
2133 Log.i(this, "handoverFailed %s", callId);
2134 onHandoverFailed(request, reason);
2135 }
2136
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002137 /**
2138 * Called by Telecom when the creation of a new Connection has completed and it is now added
2139 * to Telecom.
2140 * @param callId The ID of the connection.
2141 */
2142 private void notifyCreateConnectionComplete(final String callId) {
2143 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07002144 if (callId == null) {
2145 // This could happen if the connection fails quickly and is removed from the
2146 // ConnectionService before Telecom sends the create connection complete callback.
2147 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
2148 return;
2149 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002150 onCreateConnectionComplete(findConnectionForAction(callId,
2151 "notifyCreateConnectionComplete"));
2152 }
2153
Ravi Paluri80aa2142019-12-02 11:57:37 +05302154 /**
2155 * Called by Telecom when the creation of a new Conference has completed and it is now added
2156 * to Telecom.
2157 * @param callId The ID of the connection.
2158 */
2159 private void notifyCreateConferenceComplete(final String callId) {
2160 Log.i(this, "notifyCreateConferenceComplete %s", callId);
2161 if (callId == null) {
2162 // This could happen if the conference fails quickly and is removed from the
2163 // ConnectionService before Telecom sends the create conference complete callback.
2164 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
2165 return;
2166 }
2167 onCreateConferenceComplete(findConferenceForAction(callId,
2168 "notifyCreateConferenceComplete"));
2169 }
2170
2171
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002172 private void abort(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002173 Log.i(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002174 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002175 }
2176
Tyler Gunnbe74de02014-08-29 14:51:48 -07002177 private void answerVideo(String callId, int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002178 Log.i(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302179 if (mConnectionById.containsKey(callId)) {
2180 findConnectionForAction(callId, "answer").onAnswer(videoState);
2181 } else {
2182 findConferenceForAction(callId, "answer").onAnswer(videoState);
2183 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002184 }
2185
Tyler Gunnbe74de02014-08-29 14:51:48 -07002186 private void answer(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002187 Log.i(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302188 if (mConnectionById.containsKey(callId)) {
2189 findConnectionForAction(callId, "answer").onAnswer();
2190 } else {
2191 findConferenceForAction(callId, "answer").onAnswer();
2192 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002193 }
2194
Pooja Jaind34698d2017-12-28 14:15:31 +05302195 private void deflect(String callId, Uri address) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002196 Log.i(this, "deflect %s", callId);
Pooja Jaind34698d2017-12-28 14:15:31 +05302197 findConnectionForAction(callId, "deflect").onDeflect(address);
2198 }
2199
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002200 private void reject(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002201 Log.i(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302202 if (mConnectionById.containsKey(callId)) {
2203 findConnectionForAction(callId, "reject").onReject();
2204 } else {
2205 findConferenceForAction(callId, "reject").onReject();
2206 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002207 }
2208
Bryce Lee81901682015-08-28 16:38:02 -07002209 private void reject(String callId, String rejectWithMessage) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002210 Log.i(this, "reject %s with message", callId);
Bryce Lee81901682015-08-28 16:38:02 -07002211 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2212 }
2213
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002214 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002215 Log.i(this, "reject %s with reason %d", callId, rejectReason);
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002216 findConnectionForAction(callId, "reject").onReject(rejectReason);
2217 }
2218
Ravi Palurif4b38e72020-02-05 12:35:41 +05302219 private void transfer(String callId, Uri number, boolean isConfirmationRequired) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002220 Log.i(this, "transfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302221 findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired);
2222 }
2223
2224 private void consultativeTransfer(String callId, String otherCallId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002225 Log.i(this, "consultativeTransfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302226 Connection connection1 = findConnectionForAction(callId, "consultativeTransfer");
2227 Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer");
2228 connection1.onTransfer(connection2);
2229 }
2230
Bryce Leecac50772015-11-17 15:13:29 -08002231 private void silence(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002232 Log.i(this, "silence %s", callId);
Bryce Leecac50772015-11-17 15:13:29 -08002233 findConnectionForAction(callId, "silence").onSilence();
2234 }
2235
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002236 private void disconnect(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002237 Log.i(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002238 if (mConnectionById.containsKey(callId)) {
2239 findConnectionForAction(callId, "disconnect").onDisconnect();
2240 } else {
2241 findConferenceForAction(callId, "disconnect").onDisconnect();
2242 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002243 }
2244
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002245 private void hold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002246 Log.i(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002247 if (mConnectionById.containsKey(callId)) {
2248 findConnectionForAction(callId, "hold").onHold();
2249 } else {
2250 findConferenceForAction(callId, "hold").onHold();
2251 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002252 }
2253
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002254 private void unhold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002255 Log.i(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002256 if (mConnectionById.containsKey(callId)) {
2257 findConnectionForAction(callId, "unhold").onUnhold();
2258 } else {
2259 findConferenceForAction(callId, "unhold").onUnhold();
2260 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002261 }
2262
Yorke Lee4af59352015-05-13 14:14:54 -07002263 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002264 Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002265 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002266 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2267 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002268 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002269 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2270 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002271 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002272 }
2273
Grace Jia4e8dc102021-01-19 14:58:01 -08002274 private void onUsingAlternativeUi(String callId, boolean isUsingAlternativeUi) {
2275 Log.i(this, "onUsingAlternativeUi %s %s", callId, isUsingAlternativeUi);
2276 if (mConnectionById.containsKey(callId)) {
2277 findConnectionForAction(callId, "onUsingAlternativeUi")
2278 .onUsingAlternativeUi(isUsingAlternativeUi);
2279 }
2280 }
2281
2282 private void onTrackedByNonUiService(String callId, boolean isTracked) {
2283 Log.i(this, "onTrackedByNonUiService %s %s", callId, isTracked);
2284 if (mConnectionById.containsKey(callId)) {
2285 findConnectionForAction(callId, "onTrackedByNonUiService")
2286 .onTrackedByNonUiService(isTracked);
2287 }
2288 }
2289
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002290 private void playDtmfTone(String callId, char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002291 Log.i(this, "playDtmfTone %s %c", callId, digit);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002292 if (mConnectionById.containsKey(callId)) {
2293 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2294 } else {
2295 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2296 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002297 }
2298
2299 private void stopDtmfTone(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002300 Log.i(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002301 if (mConnectionById.containsKey(callId)) {
2302 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2303 } else {
2304 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2305 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002306 }
2307
Santos Cordon823fd3c2014-08-07 18:35:18 -07002308 private void conference(String callId1, String callId2) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002309 Log.i(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002310
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002311 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002312 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002313 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002314 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002315 conference2 = findConferenceForAction(callId2, "conference");
2316 if (conference2 == getNullConference()) {
2317 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2318 callId2);
2319 return;
2320 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002321 }
Santos Cordonb6939982014-06-04 20:20:58 -07002322
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002323 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002324 Connection connection1 = findConnectionForAction(callId1, "conference");
2325 if (connection1 == getNullConnection()) {
2326 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2327 if (conference1 == getNullConference()) {
2328 Log.w(this,
2329 "Connection1 or Conference1 missing in conference request %s.",
2330 callId1);
2331 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002332 // Call 1 is a conference.
2333 if (connection2 != getNullConnection()) {
2334 // Call 2 is a connection so merge via call 1 (conference).
2335 conference1.onMerge(connection2);
2336 } else {
2337 // Call 2 is ALSO a conference; this should never happen.
2338 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2339 "merge two conferences.");
2340 return;
2341 }
Ihab Awad50e35062014-09-30 09:17:03 -07002342 }
2343 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002344 // Call 1 is a connection.
2345 if (conference2 != getNullConference()) {
2346 // Call 2 is a conference, so merge via call 2.
2347 conference2.onMerge(connection1);
2348 } else {
2349 // Call 2 is a connection, so merge together.
2350 onConference(connection1, connection2);
2351 }
Ihab Awad50e35062014-09-30 09:17:03 -07002352 }
Santos Cordon980acb92014-05-31 10:31:19 -07002353 }
2354
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002355 private void splitFromConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002356 Log.i(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002357
2358 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002359 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002360 Log.w(this, "Connection missing in conference request %s.", callId);
2361 return;
2362 }
2363
Santos Cordon0159ac02014-08-21 14:28:11 -07002364 Conference conference = connection.getConference();
2365 if (conference != null) {
2366 conference.onSeparate(connection);
2367 }
Santos Cordon980acb92014-05-31 10:31:19 -07002368 }
2369
Santos Cordona4868042014-09-04 17:39:22 -07002370 private void mergeConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002371 Log.i(this, "mergeConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002372 Conference conference = findConferenceForAction(callId, "mergeConference");
2373 if (conference != null) {
2374 conference.onMerge();
2375 }
2376 }
2377
2378 private void swapConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002379 Log.i(this, "swapConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002380 Conference conference = findConferenceForAction(callId, "swapConference");
2381 if (conference != null) {
2382 conference.onSwap();
2383 }
2384 }
2385
Ravi Paluri404babb2020-01-23 19:02:44 +05302386 private void addConferenceParticipants(String callId, List<Uri> participants) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002387 Log.i(this, "addConferenceParticipants(%s)", callId);
Ravi Paluri404babb2020-01-23 19:02:44 +05302388 if (mConnectionById.containsKey(callId)) {
2389 findConnectionForAction(callId, "addConferenceParticipants")
2390 .onAddConferenceParticipants(participants);
2391 } else {
2392 findConferenceForAction(callId, "addConferenceParticipants")
2393 .onAddConferenceParticipants(participants);
2394 }
2395 }
2396
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002397 /**
2398 * Notifies a {@link Connection} of a request to pull an external call.
2399 *
2400 * See {@link Call#pullExternalCall()}.
2401 *
2402 * @param callId The ID of the call to pull.
2403 */
2404 private void pullExternalCall(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002405 Log.i(this, "pullExternalCall(%s)", callId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002406 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2407 if (connection != null) {
2408 connection.onPullExternalCall();
2409 }
2410 }
2411
2412 /**
2413 * Notifies a {@link Connection} of a call event.
2414 *
2415 * See {@link Call#sendCallEvent(String, Bundle)}.
2416 *
2417 * @param callId The ID of the call receiving the event.
2418 * @param event The event.
2419 * @param extras Extras associated with the event.
2420 */
2421 private void sendCallEvent(String callId, String event, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002422 Log.i(this, "sendCallEvent(%s, %s)", callId, event);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002423 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2424 if (connection != null) {
2425 connection.onCallEvent(event, extras);
2426 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002427 }
2428
Tyler Gunndee56a82016-03-23 16:06:34 -07002429 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002430 * Notifies a {@link Connection} that a handover has completed.
2431 *
2432 * @param callId The ID of the call which completed handover.
2433 */
2434 private void notifyHandoverComplete(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002435 Log.i(this, "notifyHandoverComplete(%s)", callId);
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002436 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2437 if (connection != null) {
2438 connection.onHandoverComplete();
2439 }
2440 }
2441
2442 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002443 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2444 * <p>
2445 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2446 * the {@link android.telecom.Call#putExtra(String, boolean)},
2447 * {@link android.telecom.Call#putExtra(String, int)},
2448 * {@link android.telecom.Call#putExtra(String, String)},
2449 * {@link Call#removeExtras(List)}.
2450 *
2451 * @param callId The ID of the call receiving the event.
2452 * @param extras The new extras bundle.
2453 */
2454 private void handleExtrasChanged(String callId, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002455 Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002456 if (mConnectionById.containsKey(callId)) {
2457 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2458 } else if (mConferenceById.containsKey(callId)) {
2459 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2460 }
2461 }
2462
Hall Liub64ac4c2017-02-06 10:49:48 -08002463 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002464 Log.i(this, "startRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002465 if (mConnectionById.containsKey(callId)) {
2466 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2467 } else if (mConferenceById.containsKey(callId)) {
2468 Log.w(this, "startRtt called on a conference.");
2469 }
2470 }
2471
2472 private void stopRtt(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002473 Log.i(this, "stopRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002474 if (mConnectionById.containsKey(callId)) {
2475 findConnectionForAction(callId, "stopRtt").onStopRtt();
2476 } else if (mConferenceById.containsKey(callId)) {
2477 Log.w(this, "stopRtt called on a conference.");
2478 }
2479 }
2480
2481 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002482 Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
Hall Liub64ac4c2017-02-06 10:49:48 -08002483 if (mConnectionById.containsKey(callId)) {
2484 findConnectionForAction(callId, "handleRttUpgradeResponse")
2485 .handleRttUpgradeResponse(rttTextStream);
2486 } else if (mConferenceById.containsKey(callId)) {
2487 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2488 }
2489 }
2490
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002491 private void onPostDialContinue(String callId, boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002492 Log.i(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002493 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002494 }
2495
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002496 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002497 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002498 // No need to query again if we already did it.
2499 return;
2500 }
2501
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002502 String callingPackage = getOpPackageName();
2503
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002504 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002505 @Override
2506 public void onResult(
2507 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002508 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002509 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002510 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002511 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002512 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002513 mRemoteConnectionManager.addConnectionService(
2514 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002515 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002516 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002517 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002518 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002519 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002520 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002521 }
2522
2523 @Override
2524 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002525 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002526 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002527 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002528 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002529 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002530 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002531 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002532 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002533 }
2534
Ihab Awadf8b69882014-07-25 15:14:01 -07002535 /**
2536 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002537 * incoming request. This is used by {@code ConnectionService}s that are registered with
2538 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2539 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002540 *
2541 * @param connectionManagerPhoneAccount See description at
2542 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2543 * @param request Details about the incoming call.
2544 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2545 * not handle the call.
2546 */
2547 public final RemoteConnection createRemoteIncomingConnection(
2548 PhoneAccountHandle connectionManagerPhoneAccount,
2549 ConnectionRequest request) {
2550 return mRemoteConnectionManager.createRemoteConnection(
2551 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002552 }
2553
2554 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002555 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002556 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2557 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2558 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002559 *
2560 * @param connectionManagerPhoneAccount See description at
2561 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002562 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002563 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2564 * not handle the call.
2565 */
2566 public final RemoteConnection createRemoteOutgoingConnection(
2567 PhoneAccountHandle connectionManagerPhoneAccount,
2568 ConnectionRequest request) {
2569 return mRemoteConnectionManager.createRemoteConnection(
2570 connectionManagerPhoneAccount, request, false);
2571 }
2572
2573 /**
Grace Jia9a09c672020-08-04 12:52:09 -07002574 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2575 * incoming request. This is used by {@code ConnectionService}s that are registered with
2576 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2577 *
2578 * @param connectionManagerPhoneAccount See description at
2579 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2580 * @param request Details about the incoming conference call.
2581 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2582 * handle the call.
2583 */
2584 public final @Nullable RemoteConference createRemoteIncomingConference(
2585 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2586 @Nullable ConnectionRequest request) {
2587 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2588 request, true);
2589 }
2590
2591 /**
2592 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2593 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2594 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2595 *
2596 * @param connectionManagerPhoneAccount See description at
2597 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2598 * @param request Details about the outgoing conference call.
2599 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2600 * handle the call.
2601 */
2602 public final @Nullable RemoteConference createRemoteOutgoingConference(
2603 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2604 @Nullable ConnectionRequest request) {
2605 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2606 request, false);
2607 }
2608
2609 /**
Santos Cordona663f862014-10-29 13:49:58 -07002610 * Indicates to the relevant {@code RemoteConnectionService} that the specified
2611 * {@link RemoteConnection}s should be merged into a conference call.
2612 * <p>
2613 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
2614 * be invoked.
2615 *
2616 * @param remoteConnection1 The first of the remote connections to conference.
2617 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07002618 */
2619 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07002620 RemoteConnection remoteConnection1,
2621 RemoteConnection remoteConnection2) {
2622 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07002623 }
2624
2625 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002626 * Adds a new conference call. When a conference call is created either as a result of an
2627 * explicit request via {@link #onConference} or otherwise, the connection service should supply
2628 * an instance of {@link Conference} by invoking this method. A conference call provided by this
2629 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
2630 *
2631 * @param conference The new conference object.
2632 */
2633 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07002634 Log.d(this, "addConference: conference=%s", conference);
2635
Santos Cordon823fd3c2014-08-07 18:35:18 -07002636 String id = addConferenceInternal(conference);
2637 if (id != null) {
2638 List<String> connectionIds = new ArrayList<>(2);
2639 for (Connection connection : conference.getConnections()) {
2640 if (mIdByConnection.containsKey(connection)) {
2641 connectionIds.add(mIdByConnection.get(connection));
2642 }
2643 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002644 conference.setTelecomCallId(id);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07002645 ParcelableConference parcelableConference = new ParcelableConference.Builder(
2646 conference.getPhoneAccountHandle(), conference.getState())
2647 .setConnectionCapabilities(conference.getConnectionCapabilities())
2648 .setConnectionProperties(conference.getConnectionProperties())
2649 .setConnectionIds(connectionIds)
2650 .setVideoAttributes(conference.getVideoProvider() == null
2651 ? null : conference.getVideoProvider().getInterface(),
2652 conference.getVideoState())
2653 .setConnectTimeMillis(conference.getConnectTimeMillis(),
2654 conference.getConnectionStartElapsedRealtimeMillis())
2655 .setStatusHints(conference.getStatusHints())
2656 .setExtras(conference.getExtras())
2657 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2658 .setCallerDisplayName(conference.getCallerDisplayName(),
2659 conference.getCallerDisplayNamePresentation())
2660 .setDisconnectCause(conference.getDisconnectCause())
2661 .setRingbackRequested(conference.isRingbackRequested())
2662 .setCallDirection(conference.getCallDirection())
2663 .build();
Andrew Lee0f51da32015-04-16 13:11:55 -07002664
Santos Cordon823fd3c2014-08-07 18:35:18 -07002665 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07002666 mAdapter.setVideoProvider(id, conference.getVideoProvider());
2667 mAdapter.setVideoState(id, conference.getVideoState());
Tyler Gunn10362372020-04-08 13:12:30 -07002668 // In some instances a conference can start its life as a standalone call with just a
2669 // single participant; ensure we signal to Telecom in this case.
2670 if (!conference.isMultiparty()) {
2671 mAdapter.setConferenceState(id, conference.isMultiparty());
2672 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002673
2674 // Go through any child calls and set the parent.
2675 for (Connection connection : conference.getConnections()) {
2676 String connectionId = mIdByConnection.get(connection);
2677 if (connectionId != null) {
2678 mAdapter.setIsConferenced(connectionId, id);
2679 }
2680 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002681 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002682 }
2683 }
2684
2685 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002686 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
2687 * connection.
2688 *
2689 * @param phoneAccountHandle The phone account handle for the connection.
2690 * @param connection The connection to add.
2691 */
2692 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
2693 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07002694 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
2695 }
2696
2697 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002698 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
2699 * microphone, camera).
2700 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08002701 * <p>
2702 * The {@link ConnectionService} will be disconnected when it failed to call this method within
2703 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
2704 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08002705 * @see ConnectionService#onConnectionServiceFocusLost()
2706 */
2707 public final void connectionServiceFocusReleased() {
2708 mAdapter.onConnectionServiceFocusReleased();
2709 }
2710
2711 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07002712 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07002713 * connection, as well as adding that connection to the specified conference.
2714 * <p>
2715 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
2716 * IMS conference participants to be added to a conference in a single step; this helps ensure
2717 * UI updates happen atomically, rather than adding the connection and then adding it to
2718 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07002719 *
2720 * @param phoneAccountHandle The phone account handle for the connection.
2721 * @param connection The connection to add.
2722 * @param conference The parent conference of the new connection.
2723 * @hide
2724 */
Tyler Gunn5567d742019-10-31 13:04:37 -07002725 @SystemApi
2726 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
2727 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002728
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002729 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002730 if (id != null) {
2731 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07002732 String conferenceId = null;
2733 if (conference != null) {
2734 conferenceId = mIdByConference.get(conference);
2735 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002736
2737 ParcelableConnection parcelableConnection = new ParcelableConnection(
2738 phoneAccountHandle,
2739 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002740 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002741 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002742 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002743 connection.getAddress(),
2744 connection.getAddressPresentation(),
2745 connection.getCallerDisplayName(),
2746 connection.getCallerDisplayNamePresentation(),
2747 connection.getVideoProvider() == null ?
2748 null : connection.getVideoProvider().getInterface(),
2749 connection.getVideoState(),
2750 connection.isRingbackRequested(),
2751 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002752 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002753 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002754 connection.getStatusHints(),
2755 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002756 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07002757 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07002758 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002759 connection.getCallDirection(),
2760 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002761 mAdapter.addExistingConnection(id, parcelableConnection);
2762 }
2763 }
2764
2765 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002766 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
2767 * has taken responsibility.
2768 *
2769 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07002770 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07002771 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07002772 return mConnectionById.values();
2773 }
2774
2775 /**
Santos Cordona6018b92016-02-16 14:23:12 -08002776 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
2777 * has taken responsibility.
2778 *
2779 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
2780 */
2781 public final Collection<Conference> getAllConferences() {
2782 return mConferenceById.values();
2783 }
2784
2785 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002786 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2787 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07002788 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002789 * @param connectionManagerPhoneAccount See description at
2790 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2791 * @param request Details about the incoming call.
2792 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2793 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002794 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002795 public Connection onCreateIncomingConnection(
2796 PhoneAccountHandle connectionManagerPhoneAccount,
2797 ConnectionRequest request) {
2798 return null;
2799 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302800 /**
Grace Jia8587ee52020-07-10 15:42:32 -07002801 * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
2802 * conference call initiated via
2803 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302804 *
2805 * @param connectionManagerPhoneAccount See description at
2806 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Grace Jia8587ee52020-07-10 15:42:32 -07002807 * @param request Details about the incoming conference call.
2808 * @return The {@code Conference} object to satisfy this call, or {@code null} to
Ravi Paluri80aa2142019-12-02 11:57:37 +05302809 * not handle the call.
2810 */
2811 public @Nullable Conference onCreateIncomingConference(
2812 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2813 @Nullable ConnectionRequest request) {
2814 return null;
2815 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002816
2817 /**
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002818 * Called after the {@link Connection} returned by
2819 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
2820 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
2821 * added to the {@link ConnectionService} and sent to Telecom.
2822 *
2823 * @param connection the {@link Connection}.
2824 * @hide
2825 */
2826 public void onCreateConnectionComplete(Connection connection) {
2827 }
2828
2829 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302830 * Called after the {@link Conference} returned by
2831 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
2832 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
2833 * added to the {@link ConnectionService} and sent to Telecom.
2834 *
2835 * @param conference the {@link Conference}.
2836 * @hide
2837 */
2838 public void onCreateConferenceComplete(Conference conference) {
2839 }
2840
2841
2842 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002843 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2844 * incoming {@link Connection} was denied.
2845 * <p>
2846 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2847 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
2848 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2849 * {@link Connection}.
2850 * <p>
2851 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2852 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002853 * @param connectionManagerPhoneAccount See description at
2854 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002855 * @param request The incoming connection request.
2856 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002857 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2858 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002859 }
2860
2861 /**
2862 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2863 * outgoing {@link Connection} was denied.
2864 * <p>
2865 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2866 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
2867 * The {@link ConnectionService} is responisible for informing the user that the
2868 * {@link Connection} cannot be made at this time.
2869 * <p>
2870 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2871 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002872 * @param connectionManagerPhoneAccount See description at
2873 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002874 * @param request The outgoing connection request.
2875 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002876 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2877 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002878 }
2879
2880 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302881 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2882 * incoming {@link Conference} was denied.
2883 * <p>
2884 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2885 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
2886 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2887 * {@link Conference}.
2888 * <p>
2889 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2890 *
2891 * @param connectionManagerPhoneAccount See description at
2892 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2893 * @param request The incoming connection request.
2894 */
2895 public void onCreateIncomingConferenceFailed(
2896 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2897 @Nullable ConnectionRequest request) {
2898 }
2899
2900 /**
2901 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2902 * outgoing {@link Conference} was denied.
2903 * <p>
2904 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2905 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
2906 * The {@link ConnectionService} is responisible for informing the user that the
2907 * {@link Conference} cannot be made at this time.
2908 * <p>
2909 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2910 *
2911 * @param connectionManagerPhoneAccount See description at
2912 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2913 * @param request The outgoing connection request.
2914 */
2915 public void onCreateOutgoingConferenceFailed(
2916 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2917 @Nullable ConnectionRequest request) {
2918 }
2919
2920
2921 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002922 * Trigger recalculate functinality for conference calls. This is used when a Telephony
2923 * Connection is part of a conference controller but is not yet added to Connection
2924 * Service and hence cannot be added to the conference call.
2925 *
2926 * @hide
2927 */
2928 public void triggerConferenceRecalculate() {
2929 }
2930
2931 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002932 * Create a {@code Connection} given an outgoing request. This is used to initiate new
2933 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002934 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002935 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2936 * this call.
2937 * <p>
2938 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2939 * has registered one or more {@code PhoneAccount}s having
2940 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2941 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2942 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2943 * making the connection.
2944 * <p>
2945 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2946 * being asked to make a direct connection. The
2947 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2948 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2949 * making the connection.
2950 * @param request Details about the outgoing call.
2951 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002952 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002953 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002954 public Connection onCreateOutgoingConnection(
2955 PhoneAccountHandle connectionManagerPhoneAccount,
2956 ConnectionRequest request) {
2957 return null;
2958 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002959
2960 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302961 * Create a {@code Conference} given an outgoing request. This is used to initiate new
Grace Jia8587ee52020-07-10 15:42:32 -07002962 * outgoing conference call requested via
2963 * {@link TelecomManager#startConference(List, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302964 *
2965 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2966 * this call.
2967 * <p>
2968 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2969 * has registered one or more {@code PhoneAccount}s having
2970 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2971 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2972 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2973 * making the connection.
2974 * <p>
2975 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2976 * being asked to make a direct connection. The
2977 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2978 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2979 * making the connection.
2980 * @param request Details about the outgoing call.
2981 * @return The {@code Conference} object to satisfy this call, or the result of an invocation
2982 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
2983 */
2984 public @Nullable Conference onCreateOutgoingConference(
2985 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2986 @Nullable ConnectionRequest request) {
2987 return null;
2988 }
2989
2990
2991 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08002992 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
2993 * outgoing handover {@link Connection}.
2994 * <p>
2995 * A call handover is the process where an ongoing call is transferred from one app (i.e.
2996 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
2997 * mobile network call in a video calling app. The mobile network call via the Telephony stack
2998 * is referred to as the source of the handover, and the video calling app is referred to as the
2999 * destination.
3000 * <p>
3001 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3002 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3003 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3004 * device.
3005 * <p>
3006 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
3007 * device when the user initiates a handover request from one app to another. The user request
3008 * originates in the {@link InCallService} via
3009 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3010 * <p>
3011 * For a full discussion of the handover process and the APIs involved, see
3012 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3013 * <p>
3014 * Implementations of this method should return an instance of {@link Connection} which
3015 * represents the handover. If your app does not wish to accept a handover to it at this time,
3016 * you can return {@code null}. The code below shows an example of how this is done.
3017 * <pre>
3018 * {@code
3019 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3020 * fromPhoneAccountHandle, ConnectionRequest request) {
3021 * if (!isHandoverAvailable()) {
3022 * return null;
3023 * }
3024 * MyConnection connection = new MyConnection();
3025 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3026 * connection.setVideoState(request.getVideoState());
3027 * return connection;
3028 * }
3029 * }
3030 * </pre>
3031 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003032 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3033 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08003034 * @param request Details about the call to handover.
3035 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003036 */
3037 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3038 ConnectionRequest request) {
3039 return null;
3040 }
3041
3042 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003043 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3044 * incoming handover {@link Connection}.
3045 * <p>
3046 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3047 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3048 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3049 * is referred to as the source of the handover, and the video calling app is referred to as the
3050 * destination.
3051 * <p>
3052 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3053 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3054 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3055 * device.
3056 * <p>
3057 * This method is called on the destination app on the <em>receiving</em> device when the
3058 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
3059 * accept an incoming handover from the <em>initiating</em> device.
3060 * <p>
3061 * For a full discussion of the handover process and the APIs involved, see
3062 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3063 * <p>
3064 * Implementations of this method should return an instance of {@link Connection} which
3065 * represents the handover. The code below shows an example of how this is done.
3066 * <pre>
3067 * {@code
3068 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3069 * fromPhoneAccountHandle, ConnectionRequest request) {
3070 * // Given that your app requested to accept the handover, you should not return null here.
3071 * MyConnection connection = new MyConnection();
3072 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3073 * connection.setVideoState(request.getVideoState());
3074 * return connection;
3075 * }
3076 * }
3077 * </pre>
3078 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003079 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3080 * ConnectionService which needs to handover the call.
3081 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08003082 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003083 */
3084 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3085 ConnectionRequest request) {
3086 return null;
3087 }
3088
3089 /**
3090 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
3091 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08003092 * <p>
3093 * For a full discussion of the handover process and the APIs involved, see
3094 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
3095 *
3096 * @param request Details about the call which failed to handover.
3097 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07003098 */
Tyler Gunn9d127732018-03-02 15:45:51 -08003099 public void onHandoverFailed(ConnectionRequest request,
3100 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07003101 return;
3102 }
3103
3104 /**
Yorke Leec3cf9822014-10-02 09:38:39 -07003105 * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
3106 * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
3107 * call created using
3108 * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
3109 *
Yorke Lee770ed6e2014-10-06 18:58:52 -07003110 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07003111 */
3112 public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
3113 ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003114 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07003115 }
3116
3117 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003118 * Conference two specified connections. Invoked when the user has made a request to merge the
3119 * specified connections into a conference call. In response, the connection service should
3120 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07003121 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07003122 * @param connection1 A connection to merge into a conference call.
3123 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07003124 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07003125 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07003126
Santos Cordona663f862014-10-29 13:49:58 -07003127 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07003128 * Called when a connection is added.
3129 * @hide
3130 */
3131 public void onConnectionAdded(Connection connection) {}
3132
3133 /**
3134 * Called when a connection is removed.
3135 * @hide
3136 */
3137 public void onConnectionRemoved(Connection connection) {}
3138
3139 /**
3140 * Called when a conference is added.
3141 * @hide
3142 */
3143 public void onConferenceAdded(Conference conference) {}
3144
3145 /**
3146 * Called when a conference is removed.
3147 * @hide
3148 */
3149 public void onConferenceRemoved(Conference conference) {}
3150
3151 /**
Santos Cordona663f862014-10-29 13:49:58 -07003152 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
3153 * When this method is invoked, this {@link ConnectionService} should create its own
3154 * representation of the conference call and send it to telecom using {@link #addConference}.
3155 * <p>
3156 * This is only relevant to {@link ConnectionService}s which are registered with
3157 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
3158 *
3159 * @param conference The remote conference call.
3160 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07003161 public void onRemoteConferenceAdded(RemoteConference conference) {}
3162
Santos Cordon823fd3c2014-08-07 18:35:18 -07003163 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003164 * Called when an existing connection is added remotely.
3165 * @param connection The existing connection which was added.
3166 */
3167 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
3168
3169 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003170 * Called when the {@link ConnectionService} has lost the call focus.
3171 * The {@link ConnectionService} should release the call resources and invokes
3172 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
3173 * released the call resources.
3174 */
3175 public void onConnectionServiceFocusLost() {}
3176
3177 /**
3178 * Called when the {@link ConnectionService} has gained the call focus. The
3179 * {@link ConnectionService} can acquire the call resources at this time.
3180 */
3181 public void onConnectionServiceFocusGained() {}
3182
3183 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003184 * @hide
3185 */
3186 public boolean containsConference(Conference conference) {
3187 return mIdByConference.containsKey(conference);
3188 }
3189
Ihab Awadb8e85c72014-08-23 20:34:57 -07003190 /** {@hide} */
3191 void addRemoteConference(RemoteConference remoteConference) {
3192 onRemoteConferenceAdded(remoteConference);
3193 }
3194
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003195 /** {@hide} */
3196 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
3197 onRemoteExistingConnectionAdded(remoteConnection);
3198 }
3199
Ihab Awad5d0410f2014-07-30 10:07:40 -07003200 private void onAccountsInitialized() {
3201 mAreAccountsInitialized = true;
3202 for (Runnable r : mPreInitializationConnectionRequests) {
3203 r.run();
3204 }
3205 mPreInitializationConnectionRequests.clear();
3206 }
3207
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003208 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003209 * Adds an existing connection to the list of connections, identified by a new call ID unique
3210 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003211 *
3212 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003213 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003214 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003215 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
3216 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003217
3218 if (connection.getExtras() != null && connection.getExtras()
3219 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3220 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3221 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
3222 connection.getTelecomCallId(), id);
3223 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003224 // If no phone account handle was provided, we cannot be sure the call ID is unique,
3225 // so just use a random UUID.
3226 id = UUID.randomUUID().toString();
3227 } else {
3228 // Phone account handle was provided, so use the ConnectionService class name as a
3229 // prefix for a unique incremental call ID.
3230 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
3231 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003232 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003233 return id;
3234 }
3235
Pengquan Meng70c9885332017-10-02 18:09:03 -07003236 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003237 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003238 mConnectionById.put(callId, connection);
3239 mIdByConnection.put(connection, callId);
3240 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003241 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003242 connection.setPhoneAccountHandle(handle);
3243 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003244 }
3245
Anthony Lee30e65842014-11-06 16:30:53 -08003246 /** {@hide} */
3247 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003248 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003249 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003250 String id = mIdByConnection.get(connection);
3251 if (id != null) {
3252 mConnectionById.remove(id);
3253 mIdByConnection.remove(connection);
3254 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003255 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003256 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003257 }
3258
Santos Cordon823fd3c2014-08-07 18:35:18 -07003259 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003260 String originalId = null;
3261 if (conference.getExtras() != null && conference.getExtras()
3262 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3263 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3264 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3265 conference.getTelecomCallId(),
3266 originalId);
3267 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003268 if (mIdByConference.containsKey(conference)) {
3269 Log.w(this, "Re-adding an existing conference: %s.", conference);
3270 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003271 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3272 // cannot determine a ConnectionService class name to associate with the ID, so use
3273 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003274 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003275 mConferenceById.put(id, conference);
3276 mIdByConference.put(conference, id);
3277 conference.addListener(mConferenceListener);
3278 return id;
3279 }
3280
3281 return null;
3282 }
3283
3284 private void removeConference(Conference conference) {
3285 if (mIdByConference.containsKey(conference)) {
3286 conference.removeListener(mConferenceListener);
3287
3288 String id = mIdByConference.get(conference);
3289 mConferenceById.remove(id);
3290 mIdByConference.remove(conference);
3291 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003292
3293 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003294 }
3295 }
3296
Ihab Awad542e0ea2014-05-16 10:22:16 -07003297 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003298 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003299 return mConnectionById.get(callId);
3300 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003301 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003302 return getNullConnection();
3303 }
3304
3305 static synchronized Connection getNullConnection() {
3306 if (sNullConnection == null) {
3307 sNullConnection = new Connection() {};
3308 }
3309 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003310 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003311
3312 private Conference findConferenceForAction(String conferenceId, String action) {
3313 if (mConferenceById.containsKey(conferenceId)) {
3314 return mConferenceById.get(conferenceId);
3315 }
3316 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3317 return getNullConference();
3318 }
3319
Ihab Awadb8e85c72014-08-23 20:34:57 -07003320 private List<String> createConnectionIdList(List<Connection> connections) {
3321 List<String> ids = new ArrayList<>();
3322 for (Connection c : connections) {
3323 if (mIdByConnection.containsKey(c)) {
3324 ids.add(mIdByConnection.get(c));
3325 }
3326 }
3327 Collections.sort(ids);
3328 return ids;
3329 }
3330
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003331 /**
3332 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003333 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003334 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003335 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003336 * @return List of string conference and call Ids.
3337 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003338 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003339 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003340 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003341 // Only allow Connection and Conference conferenceables.
3342 if (c instanceof Connection) {
3343 Connection connection = (Connection) c;
3344 if (mIdByConnection.containsKey(connection)) {
3345 ids.add(mIdByConnection.get(connection));
3346 }
3347 } else if (c instanceof Conference) {
3348 Conference conference = (Conference) c;
3349 if (mIdByConference.containsKey(conference)) {
3350 ids.add(mIdByConference.get(conference));
3351 }
3352 }
3353 }
3354 Collections.sort(ids);
3355 return ids;
3356 }
3357
Santos Cordon0159ac02014-08-21 14:28:11 -07003358 private Conference getNullConference() {
3359 if (sNullConference == null) {
3360 sNullConference = new Conference(null) {};
3361 }
3362 return sNullConference;
3363 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003364
3365 private void endAllConnections() {
3366 // Unbound from telecomm. We should end all connections and conferences.
3367 for (Connection connection : mIdByConnection.keySet()) {
3368 // only operate on top-level calls. Conference calls will be removed on their own.
3369 if (connection.getConference() == null) {
3370 connection.onDisconnect();
3371 }
3372 }
3373 for (Conference conference : mIdByConference.keySet()) {
3374 conference.onDisconnect();
3375 }
3376 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003377
3378 /**
3379 * Retrieves the next call ID as maintainted by the connection service.
3380 *
3381 * @return The call ID.
3382 */
3383 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003384 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003385 return ++mId;
3386 }
3387 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003388
3389 /**
3390 * Returns this handler, ONLY FOR TESTING.
3391 * @hide
3392 */
3393 @VisibleForTesting
3394 public Handler getHandler() {
3395 return mHandler;
3396 }
Santos Cordon980acb92014-05-31 10:31:19 -07003397}