blob: c189b19c71af695b38cc664c601bde5b7747fafa [file] [log] [blame]
Ihab Awad542e0ea2014-05-16 10:22:16 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Ihab Awad542e0ea2014-05-16 10:22:16 -070018
Tyler Gunn5567d742019-10-31 13:04:37 -070019import android.annotation.NonNull;
20import android.annotation.Nullable;
Santos Cordon5c6fa952014-07-20 17:47:12 -070021import android.annotation.SdkConstant;
Tyler Gunn5567d742019-10-31 13:04:37 -070022import android.annotation.SystemApi;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070023import android.app.Service;
Santos Cordon52d8a152014-06-17 19:08:45 -070024import android.content.ComponentName;
Santos Cordon5c6fa952014-07-20 17:47:12 -070025import android.content.Intent;
Ihab Awad542e0ea2014-05-16 10:22:16 -070026import android.net.Uri;
Santos Cordon6b7f9552015-05-27 17:21:45 -070027import android.os.Bundle;
Santos Cordon52d8a152014-06-17 19:08:45 -070028import android.os.Handler;
29import android.os.IBinder;
30import android.os.Looper;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070031import android.os.Message;
Hall Liub64ac4c2017-02-06 10:49:48 -080032import android.os.ParcelFileDescriptor;
33import android.os.RemoteException;
Brad Ebingerb32d4f82016-10-24 16:40:49 -070034import android.telecom.Logging.Session;
Andrew Lee14185762014-07-25 09:41:56 -070035
Brad Ebinger99f17ce2019-09-11 18:06:51 -070036import com.android.internal.annotations.VisibleForTesting;
Sailesh Nepal2a46b902014-07-04 17:21:07 -070037import com.android.internal.os.SomeArgs;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070038import com.android.internal.telecom.IConnectionService;
39import com.android.internal.telecom.IConnectionServiceAdapter;
40import com.android.internal.telecom.RemoteServiceCallback;
Santos Cordon52d8a152014-06-17 19:08:45 -070041
Ihab Awad5d0410f2014-07-30 10:07:40 -070042import java.util.ArrayList;
Santos Cordonb6939982014-06-04 20:20:58 -070043import java.util.Collection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -070044import java.util.Collections;
Santos Cordon52d8a152014-06-17 19:08:45 -070045import java.util.List;
Ihab Awad542e0ea2014-05-16 10:22:16 -070046import java.util.Map;
Santos Cordon823fd3c2014-08-07 18:35:18 -070047import java.util.UUID;
mike dooley95e80702014-09-18 14:07:52 -070048import java.util.concurrent.ConcurrentHashMap;
Ihab Awad542e0ea2014-05-16 10:22:16 -070049
50/**
Tyler Gunnf5035432017-01-09 09:43:12 -080051 * An abstract service that should be implemented by any apps which either:
52 * <ol>
53 * <li>Can make phone calls (VoIP or otherwise) and want those calls to be integrated into the
54 * built-in phone app. Referred to as a <b>system managed</b> {@link ConnectionService}.</li>
55 * <li>Are a standalone calling app and don't want their calls to be integrated into the
56 * built-in phone app. Referred to as a <b>self managed</b> {@link ConnectionService}.</li>
57 * </ol>
58 * Once implemented, the {@link ConnectionService} needs to take the following steps so that Telecom
59 * will bind to it:
Santos Cordona663f862014-10-29 13:49:58 -070060 * <p>
61 * 1. <i>Registration in AndroidManifest.xml</i>
62 * <br/>
63 * <pre>
64 * &lt;service android:name="com.example.package.MyConnectionService"
65 * android:label="@string/some_label_for_my_connection_service"
Yorke Lee249c12e2015-05-13 15:59:29 -070066 * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"&gt;
Santos Cordona663f862014-10-29 13:49:58 -070067 * &lt;intent-filter&gt;
68 * &lt;action android:name="android.telecom.ConnectionService" /&gt;
69 * &lt;/intent-filter&gt;
70 * &lt;/service&gt;
71 * </pre>
72 * <p>
73 * 2. <i> Registration of {@link PhoneAccount} with {@link TelecomManager}.</i>
74 * <br/>
75 * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
76 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080077 * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
kopriva82c591b2018-10-08 15:57:00 -070078 * before Telecom will bind to them. Self-managed {@link ConnectionService}s must be granted the
Tyler Gunnf5035432017-01-09 09:43:12 -080079 * appropriate permission before Telecom will bind to them.
80 * <p>
81 * Once registered and enabled by the user in the phone app settings or granted permission, telecom
82 * will bind to a {@link ConnectionService} implementation when it wants that
83 * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
84 * call through {@link TelecomManager#addNewIncomingCall}. The {@link ConnectionService} can then
85 * expect a call to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection}
86 * wherein it should provide a new instance of a {@link Connection} object. It is through this
87 * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
Santos Cordona663f862014-10-29 13:49:58 -070088 * receives call-commands such as answer, reject, hold and disconnect.
89 * <p>
Tyler Gunnf5035432017-01-09 09:43:12 -080090 * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
Ihab Awad542e0ea2014-05-16 10:22:16 -070091 */
Sailesh Nepal2a46b902014-07-04 17:21:07 -070092public abstract class ConnectionService extends Service {
Santos Cordon5c6fa952014-07-20 17:47:12 -070093 /**
94 * The {@link Intent} that must be declared as handled by the service.
95 */
Ihab Awadb19a0bc2014-08-07 19:46:01 -070096 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
Tyler Gunnef9f6f92014-09-12 22:16:17 -070097 public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
Santos Cordon5c6fa952014-07-20 17:47:12 -070098
Tyler Gunn8bf76572017-04-06 15:30:08 -070099 /**
100 * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
101 * being asked to create a new outgoing {@link Connection} is to perform a handover of an
102 * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}. Will
103 * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
104 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
105 * <p>
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700106 * When your {@link ConnectionService} receives this extra, it should communicate the fact that
107 * this is a handover to the other device's matching {@link ConnectionService}. That
Tyler Gunn8bf76572017-04-06 15:30:08 -0700108 * {@link ConnectionService} will continue the handover using
109 * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
Tyler Gunn727c6bd2017-04-11 09:51:40 -0700110 * {@link TelecomManager#EXTRA_IS_HANDOVER}. Telecom will match the phone numbers of the
111 * handover call on the other device with ongoing calls for {@link ConnectionService}s which
112 * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
Tyler Gunn8bf76572017-04-06 15:30:08 -0700113 * @hide
114 */
115 public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
116
Ihab Awad542e0ea2014-05-16 10:22:16 -0700117 // Flag controlling whether PII is emitted into the logs
Ihab Awad60ac30b2014-05-20 22:32:12 -0700118 private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
Ihab Awad542e0ea2014-05-16 10:22:16 -0700119
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700120 // Session Definitions
121 private static final String SESSION_HANDLER = "H.";
122 private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
123 private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
124 private static final String SESSION_CREATE_CONN = "CS.crCo";
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700125 private static final String SESSION_CREATE_CONN_COMPLETE = "CS.crCoC";
Tyler Gunn44e01912017-01-31 10:49:05 -0800126 private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700127 private static final String SESSION_ABORT = "CS.ab";
128 private static final String SESSION_ANSWER = "CS.an";
129 private static final String SESSION_ANSWER_VIDEO = "CS.anV";
Pooja Jaind34698d2017-12-28 14:15:31 +0530130 private static final String SESSION_DEFLECT = "CS.def";
Ravi Palurif4b38e72020-02-05 12:35:41 +0530131 private static final String SESSION_TRANSFER = "CS.trans";
132 private static final String SESSION_CONSULTATIVE_TRANSFER = "CS.cTrans";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700133 private static final String SESSION_REJECT = "CS.r";
134 private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
135 private static final String SESSION_SILENCE = "CS.s";
136 private static final String SESSION_DISCONNECT = "CS.d";
137 private static final String SESSION_HOLD = "CS.h";
138 private static final String SESSION_UNHOLD = "CS.u";
139 private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
Grace Jiae99fde92021-01-19 14:58:01 -0800140 private static final String SESSION_USING_ALTERNATIVE_UI = "CS.uAU";
141 private static final String SESSION_TRACKED_BY_NON_UI_SERVICE = "CS.tBNUS";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700142 private static final String SESSION_PLAY_DTMF = "CS.pDT";
143 private static final String SESSION_STOP_DTMF = "CS.sDT";
144 private static final String SESSION_CONFERENCE = "CS.c";
145 private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
146 private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
147 private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
Ravi Paluri404babb2020-01-23 19:02:44 +0530148 private static final String SESSION_ADD_PARTICIPANT = "CS.aP";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700149 private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
150 private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
151 private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
Hall Liu49cabcc2021-01-15 11:41:48 -0800152 private static final String SESSION_CALL_FILTERING_COMPLETED = "CS.oCFC";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800153 private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700154 private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
Hall Liub64ac4c2017-02-06 10:49:48 -0800155 private static final String SESSION_START_RTT = "CS.+RTT";
Hall Liua549fed2018-02-09 16:40:03 -0800156 private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
Hall Liub64ac4c2017-02-06 10:49:48 -0800157 private static final String SESSION_STOP_RTT = "CS.-RTT";
158 private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
Pengquan Meng731c1a32017-11-21 18:01:13 -0800159 private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
160 private static final String SESSION_CONNECTION_SERVICE_FOCUS_GAINED = "CS.cSFG";
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800161 private static final String SESSION_HANDOVER_FAILED = "CS.haF";
Ravi Paluri80aa2142019-12-02 11:57:37 +0530162 private static final String SESSION_CREATE_CONF = "CS.crConf";
163 private static final String SESSION_CREATE_CONF_COMPLETE = "CS.crConfC";
164 private static final String SESSION_CREATE_CONF_FAILED = "CS.crConfF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700165
Ihab Awad8aecfed2014-08-08 17:06:11 -0700166 private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700167 private static final int MSG_CREATE_CONNECTION = 2;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700168 private static final int MSG_ABORT = 3;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700169 private static final int MSG_ANSWER = 4;
170 private static final int MSG_REJECT = 5;
171 private static final int MSG_DISCONNECT = 6;
172 private static final int MSG_HOLD = 7;
173 private static final int MSG_UNHOLD = 8;
Yorke Lee4af59352015-05-13 14:14:54 -0700174 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700175 private static final int MSG_PLAY_DTMF_TONE = 10;
176 private static final int MSG_STOP_DTMF_TONE = 11;
177 private static final int MSG_CONFERENCE = 12;
178 private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700179 private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700180 private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
Tyler Gunnbe74de02014-08-29 14:51:48 -0700181 private static final int MSG_ANSWER_VIDEO = 17;
Santos Cordona4868042014-09-04 17:39:22 -0700182 private static final int MSG_MERGE_CONFERENCE = 18;
183 private static final int MSG_SWAP_CONFERENCE = 19;
Bryce Lee81901682015-08-28 16:38:02 -0700184 private static final int MSG_REJECT_WITH_MESSAGE = 20;
Bryce Leecac50772015-11-17 15:13:29 -0800185 private static final int MSG_SILENCE = 21;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700186 private static final int MSG_PULL_EXTERNAL_CALL = 22;
187 private static final int MSG_SEND_CALL_EVENT = 23;
Tyler Gunndee56a82016-03-23 16:06:34 -0700188 private static final int MSG_ON_EXTRAS_CHANGED = 24;
Tyler Gunn44e01912017-01-31 10:49:05 -0800189 private static final int MSG_CREATE_CONNECTION_FAILED = 25;
Hall Liub64ac4c2017-02-06 10:49:48 -0800190 private static final int MSG_ON_START_RTT = 26;
191 private static final int MSG_ON_STOP_RTT = 27;
192 private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700193 private static final int MSG_CREATE_CONNECTION_COMPLETE = 29;
Pengquan Meng731c1a32017-11-21 18:01:13 -0800194 private static final int MSG_CONNECTION_SERVICE_FOCUS_LOST = 30;
195 private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800196 private static final int MSG_HANDOVER_FAILED = 32;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800197 private static final int MSG_HANDOVER_COMPLETE = 33;
Pooja Jaind34698d2017-12-28 14:15:31 +0530198 private static final int MSG_DEFLECT = 34;
Ravi Paluri80aa2142019-12-02 11:57:37 +0530199 private static final int MSG_CREATE_CONFERENCE = 35;
200 private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
201 private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800202 private static final int MSG_REJECT_WITH_REASON = 38;
Ravi Paluri404babb2020-01-23 19:02:44 +0530203 private static final int MSG_ADD_PARTICIPANT = 39;
Ravi Palurif4b38e72020-02-05 12:35:41 +0530204 private static final int MSG_EXPLICIT_CALL_TRANSFER = 40;
205 private static final int MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE = 41;
Hall Liu49cabcc2021-01-15 11:41:48 -0800206 private static final int MSG_ON_CALL_FILTERING_COMPLETED = 42;
Grace Jiae99fde92021-01-19 14:58:01 -0800207 private static final int MSG_ON_USING_ALTERNATIVE_UI = 43;
208 private static final int MSG_ON_TRACKED_BY_NON_UI_SERVICE = 44;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700209
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700210 private static Connection sNullConnection;
211
mike dooley95e80702014-09-18 14:07:52 -0700212 private final Map<String, Connection> mConnectionById = new ConcurrentHashMap<>();
213 private final Map<Connection, String> mIdByConnection = new ConcurrentHashMap<>();
214 private final Map<String, Conference> mConferenceById = new ConcurrentHashMap<>();
215 private final Map<Conference, String> mIdByConference = new ConcurrentHashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700216 private final RemoteConnectionManager mRemoteConnectionManager =
217 new RemoteConnectionManager(this);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700218 private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700219 private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
Ihab Awad542e0ea2014-05-16 10:22:16 -0700220
Santos Cordon823fd3c2014-08-07 18:35:18 -0700221 private boolean mAreAccountsInitialized = false;
Santos Cordon0159ac02014-08-21 14:28:11 -0700222 private Conference sNullConference;
Tyler Gunnf0500bd2015-09-01 10:59:48 -0700223 private Object mIdSyncRoot = new Object();
224 private int mId = 0;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700225
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700226 private final IBinder mBinder = new IConnectionService.Stub() {
227 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700228 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
229 Session.Info sessionInfo) {
230 Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
231 try {
232 SomeArgs args = SomeArgs.obtain();
233 args.arg1 = adapter;
234 args.arg2 = Log.createSubsession();
235 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
236 } finally {
237 Log.endSession();
238 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700239 }
240
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700241 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
242 Session.Info sessionInfo) {
243 Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
244 try {
245 SomeArgs args = SomeArgs.obtain();
246 args.arg1 = adapter;
247 args.arg2 = Log.createSubsession();
248 mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
249 } finally {
250 Log.endSession();
251 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700252 }
253
254 @Override
Ihab Awadf8b69882014-07-25 15:14:01 -0700255 public void createConnection(
256 PhoneAccountHandle connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700257 String id,
Ihab Awadf8b69882014-07-25 15:14:01 -0700258 ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700259 boolean isIncoming,
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700260 boolean isUnknown,
261 Session.Info sessionInfo) {
262 Log.startSession(sessionInfo, SESSION_CREATE_CONN);
263 try {
264 SomeArgs args = SomeArgs.obtain();
265 args.arg1 = connectionManagerPhoneAccount;
266 args.arg2 = id;
267 args.arg3 = request;
268 args.arg4 = Log.createSubsession();
269 args.argi1 = isIncoming ? 1 : 0;
270 args.argi2 = isUnknown ? 1 : 0;
271 mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
272 } finally {
273 Log.endSession();
274 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700275 }
276
277 @Override
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700278 public void createConnectionComplete(String id, Session.Info sessionInfo) {
279 Log.startSession(sessionInfo, SESSION_CREATE_CONN_COMPLETE);
280 try {
281 SomeArgs args = SomeArgs.obtain();
282 args.arg1 = id;
283 args.arg2 = Log.createSubsession();
284 mHandler.obtainMessage(MSG_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
285 } finally {
286 Log.endSession();
287 }
288 }
289
290 @Override
Tyler Gunn44e01912017-01-31 10:49:05 -0800291 public void createConnectionFailed(
Tyler Gunn159f35c2017-03-02 09:28:37 -0800292 PhoneAccountHandle connectionManagerPhoneAccount,
Tyler Gunn44e01912017-01-31 10:49:05 -0800293 String callId,
294 ConnectionRequest request,
295 boolean isIncoming,
296 Session.Info sessionInfo) {
297 Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
298 try {
299 SomeArgs args = SomeArgs.obtain();
300 args.arg1 = callId;
301 args.arg2 = request;
302 args.arg3 = Log.createSubsession();
Tyler Gunn159f35c2017-03-02 09:28:37 -0800303 args.arg4 = connectionManagerPhoneAccount;
Tyler Gunn44e01912017-01-31 10:49:05 -0800304 args.argi1 = isIncoming ? 1 : 0;
305 mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
306 } finally {
307 Log.endSession();
308 }
309 }
310
311 @Override
Ravi Paluri80aa2142019-12-02 11:57:37 +0530312 public void createConference(
313 PhoneAccountHandle connectionManagerPhoneAccount,
314 String id,
315 ConnectionRequest request,
316 boolean isIncoming,
317 boolean isUnknown,
318 Session.Info sessionInfo) {
319 Log.startSession(sessionInfo, SESSION_CREATE_CONF);
320 try {
321 SomeArgs args = SomeArgs.obtain();
322 args.arg1 = connectionManagerPhoneAccount;
323 args.arg2 = id;
324 args.arg3 = request;
325 args.arg4 = Log.createSubsession();
326 args.argi1 = isIncoming ? 1 : 0;
327 args.argi2 = isUnknown ? 1 : 0;
328 mHandler.obtainMessage(MSG_CREATE_CONFERENCE, args).sendToTarget();
329 } finally {
330 Log.endSession();
331 }
332 }
333
334 @Override
335 public void createConferenceComplete(String id, Session.Info sessionInfo) {
336 Log.startSession(sessionInfo, SESSION_CREATE_CONF_COMPLETE);
337 try {
338 SomeArgs args = SomeArgs.obtain();
339 args.arg1 = id;
340 args.arg2 = Log.createSubsession();
341 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_COMPLETE, args).sendToTarget();
342 } finally {
343 Log.endSession();
344 }
345 }
346
347 @Override
348 public void createConferenceFailed(
349 PhoneAccountHandle connectionManagerPhoneAccount,
350 String callId,
351 ConnectionRequest request,
352 boolean isIncoming,
353 Session.Info sessionInfo) {
354 Log.startSession(sessionInfo, SESSION_CREATE_CONF_FAILED);
355 try {
356 SomeArgs args = SomeArgs.obtain();
357 args.arg1 = callId;
358 args.arg2 = request;
359 args.arg3 = Log.createSubsession();
360 args.arg4 = connectionManagerPhoneAccount;
361 args.argi1 = isIncoming ? 1 : 0;
362 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_FAILED, args).sendToTarget();
363 } finally {
364 Log.endSession();
365 }
366 }
367
368 @Override
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800369 public void handoverFailed(String callId, ConnectionRequest request, int reason,
370 Session.Info sessionInfo) {
371 Log.startSession(sessionInfo, SESSION_HANDOVER_FAILED);
372 try {
373 SomeArgs args = SomeArgs.obtain();
374 args.arg1 = callId;
375 args.arg2 = request;
376 args.arg3 = Log.createSubsession();
377 args.arg4 = reason;
378 mHandler.obtainMessage(MSG_HANDOVER_FAILED, args).sendToTarget();
379 } finally {
380 Log.endSession();
381 }
382 }
383
384 @Override
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800385 public void handoverComplete(String callId, Session.Info sessionInfo) {
386 Log.startSession(sessionInfo, SESSION_HANDOVER_COMPLETE);
387 try {
388 SomeArgs args = SomeArgs.obtain();
389 args.arg1 = callId;
390 args.arg2 = Log.createSubsession();
391 mHandler.obtainMessage(MSG_HANDOVER_COMPLETE, args).sendToTarget();
392 } finally {
393 Log.endSession();
394 }
395 }
396
397 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700398 public void abort(String callId, Session.Info sessionInfo) {
399 Log.startSession(sessionInfo, SESSION_ABORT);
400 try {
401 SomeArgs args = SomeArgs.obtain();
402 args.arg1 = callId;
403 args.arg2 = Log.createSubsession();
404 mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
405 } finally {
406 Log.endSession();
407 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700408 }
409
410 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700411 public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
412 Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
413 try {
414 SomeArgs args = SomeArgs.obtain();
415 args.arg1 = callId;
416 args.arg2 = Log.createSubsession();
417 args.argi1 = videoState;
418 mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
419 } finally {
420 Log.endSession();
421 }
Tyler Gunnbe74de02014-08-29 14:51:48 -0700422 }
423
424 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700425 public void answer(String callId, Session.Info sessionInfo) {
426 Log.startSession(sessionInfo, SESSION_ANSWER);
427 try {
428 SomeArgs args = SomeArgs.obtain();
429 args.arg1 = callId;
430 args.arg2 = Log.createSubsession();
431 mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
432 } finally {
433 Log.endSession();
434 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700435 }
436
437 @Override
Pooja Jaind34698d2017-12-28 14:15:31 +0530438 public void deflect(String callId, Uri address, Session.Info sessionInfo) {
439 Log.startSession(sessionInfo, SESSION_DEFLECT);
440 try {
441 SomeArgs args = SomeArgs.obtain();
442 args.arg1 = callId;
443 args.arg2 = address;
444 args.arg3 = Log.createSubsession();
445 mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
446 } finally {
447 Log.endSession();
448 }
449 }
450
451 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700452 public void reject(String callId, Session.Info sessionInfo) {
453 Log.startSession(sessionInfo, SESSION_REJECT);
454 try {
455 SomeArgs args = SomeArgs.obtain();
456 args.arg1 = callId;
457 args.arg2 = Log.createSubsession();
458 mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
459 } finally {
460 Log.endSession();
461 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700462 }
463
464 @Override
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800465 public void rejectWithReason(String callId,
466 @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
467 Log.startSession(sessionInfo, SESSION_REJECT);
468 try {
469 SomeArgs args = SomeArgs.obtain();
470 args.arg1 = callId;
471 args.argi1 = rejectReason;
472 args.arg2 = Log.createSubsession();
473 mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
474 } finally {
475 Log.endSession();
476 }
477 }
478
479 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700480 public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
481 Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
482 try {
483 SomeArgs args = SomeArgs.obtain();
484 args.arg1 = callId;
485 args.arg2 = message;
486 args.arg3 = Log.createSubsession();
487 mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
488 } finally {
489 Log.endSession();
490 }
Bryce Lee81901682015-08-28 16:38:02 -0700491 }
492
493 @Override
Ravi Palurif4b38e72020-02-05 12:35:41 +0530494 public void transfer(@NonNull String callId, @NonNull Uri number,
495 boolean isConfirmationRequired, Session.Info sessionInfo) {
496 Log.startSession(sessionInfo, SESSION_TRANSFER);
497 try {
498 SomeArgs args = SomeArgs.obtain();
499 args.arg1 = callId;
500 args.arg2 = number;
501 args.argi1 = isConfirmationRequired ? 1 : 0;
502 args.arg3 = Log.createSubsession();
503 mHandler.obtainMessage(MSG_EXPLICIT_CALL_TRANSFER, args).sendToTarget();
504 } finally {
505 Log.endSession();
506 }
507 }
508
509 @Override
510 public void consultativeTransfer(@NonNull String callId, @NonNull String otherCallId,
511 Session.Info sessionInfo) {
512 Log.startSession(sessionInfo, SESSION_CONSULTATIVE_TRANSFER);
513 try {
514 SomeArgs args = SomeArgs.obtain();
515 args.arg1 = callId;
516 args.arg2 = otherCallId;
517 args.arg3 = Log.createSubsession();
518 mHandler.obtainMessage(
519 MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE, args).sendToTarget();
520 } finally {
521 Log.endSession();
522 }
523 }
524
525 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700526 public void silence(String callId, Session.Info sessionInfo) {
527 Log.startSession(sessionInfo, SESSION_SILENCE);
528 try {
529 SomeArgs args = SomeArgs.obtain();
530 args.arg1 = callId;
531 args.arg2 = Log.createSubsession();
532 mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
533 } finally {
534 Log.endSession();
535 }
Bryce Leecac50772015-11-17 15:13:29 -0800536 }
537
538 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700539 public void disconnect(String callId, Session.Info sessionInfo) {
540 Log.startSession(sessionInfo, SESSION_DISCONNECT);
541 try {
542 SomeArgs args = SomeArgs.obtain();
543 args.arg1 = callId;
544 args.arg2 = Log.createSubsession();
545 mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
546 } finally {
547 Log.endSession();
548 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700549 }
550
551 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700552 public void hold(String callId, Session.Info sessionInfo) {
553 Log.startSession(sessionInfo, SESSION_HOLD);
554 try {
555 SomeArgs args = SomeArgs.obtain();
556 args.arg1 = callId;
557 args.arg2 = Log.createSubsession();
558 mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
559 } finally {
560 Log.endSession();
561 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700562 }
563
564 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700565 public void unhold(String callId, Session.Info sessionInfo) {
566 Log.startSession(sessionInfo, SESSION_UNHOLD);
567 try {
568 SomeArgs args = SomeArgs.obtain();
569 args.arg1 = callId;
570 args.arg2 = Log.createSubsession();
571 mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
572 } finally {
573 Log.endSession();
574 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700575 }
576
577 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700578 public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
579 Session.Info sessionInfo) {
580 Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
581 try {
582 SomeArgs args = SomeArgs.obtain();
583 args.arg1 = callId;
584 args.arg2 = callAudioState;
585 args.arg3 = Log.createSubsession();
586 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
587 } finally {
588 Log.endSession();
589 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700590 }
591
592 @Override
Grace Jiae99fde92021-01-19 14:58:01 -0800593 public void onUsingAlternativeUi(String callId, boolean usingAlternativeUiShowing,
594 Session.Info sessionInfo) {
595 Log.startSession(sessionInfo, SESSION_USING_ALTERNATIVE_UI);
596 try {
597 SomeArgs args = SomeArgs.obtain();
598 args.arg1 = callId;
599 args.arg2 = usingAlternativeUiShowing;
600 args.arg3 = Log.createSubsession();
601 mHandler.obtainMessage(MSG_ON_USING_ALTERNATIVE_UI, args).sendToTarget();
602 } finally {
603 Log.endSession();
604 }
605 }
606
607 @Override
608 public void onTrackedByNonUiService(String callId, boolean isTracked,
609 Session.Info sessionInfo) {
610 Log.startSession(sessionInfo, SESSION_TRACKED_BY_NON_UI_SERVICE);
611 try {
612 SomeArgs args = SomeArgs.obtain();
613 args.arg1 = callId;
614 args.arg2 = isTracked;
615 args.arg3 = Log.createSubsession();
616 mHandler.obtainMessage(MSG_ON_TRACKED_BY_NON_UI_SERVICE, args).sendToTarget();
617 } finally {
618 Log.endSession();
619 }
620 }
621
622 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700623 public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
624 Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
625 try {
626 SomeArgs args = SomeArgs.obtain();
627 args.arg1 = digit;
628 args.arg2 = callId;
629 args.arg3 = Log.createSubsession();
630 mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, args).sendToTarget();
631 } finally {
632 Log.endSession();
633 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700634 }
635
636 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700637 public void stopDtmfTone(String callId, Session.Info sessionInfo) {
638 Log.startSession(sessionInfo, SESSION_STOP_DTMF);
639 try {
640 SomeArgs args = SomeArgs.obtain();
641 args.arg1 = callId;
642 args.arg2 = Log.createSubsession();
643 mHandler.obtainMessage(MSG_STOP_DTMF_TONE, args).sendToTarget();
644 } finally {
645 Log.endSession();
646 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700647 }
648
649 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700650 public void conference(String callId1, String callId2, Session.Info sessionInfo) {
651 Log.startSession(sessionInfo, SESSION_CONFERENCE);
652 try {
653 SomeArgs args = SomeArgs.obtain();
654 args.arg1 = callId1;
655 args.arg2 = callId2;
656 args.arg3 = Log.createSubsession();
657 mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
658 } finally {
659 Log.endSession();
660 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700661 }
662
663 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700664 public void splitFromConference(String callId, Session.Info sessionInfo) {
665 Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
666 try {
667 SomeArgs args = SomeArgs.obtain();
668 args.arg1 = callId;
669 args.arg2 = Log.createSubsession();
670 mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
671 } finally {
672 Log.endSession();
673 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700674 }
675
676 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700677 public void mergeConference(String callId, Session.Info sessionInfo) {
678 Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
679 try {
680 SomeArgs args = SomeArgs.obtain();
681 args.arg1 = callId;
682 args.arg2 = Log.createSubsession();
683 mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
684 } finally {
685 Log.endSession();
686 }
Santos Cordona4868042014-09-04 17:39:22 -0700687 }
688
689 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700690 public void swapConference(String callId, Session.Info sessionInfo) {
691 Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
692 try {
693 SomeArgs args = SomeArgs.obtain();
694 args.arg1 = callId;
695 args.arg2 = Log.createSubsession();
696 mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
697 } finally {
698 Log.endSession();
699 }
Santos Cordona4868042014-09-04 17:39:22 -0700700 }
701
702 @Override
Ravi Paluri404babb2020-01-23 19:02:44 +0530703 public void addConferenceParticipants(String callId, List<Uri> participants,
704 Session.Info sessionInfo) {
705 Log.startSession(sessionInfo, SESSION_ADD_PARTICIPANT);
706 try {
707 SomeArgs args = SomeArgs.obtain();
708 args.arg1 = callId;
709 args.arg2 = participants;
710 args.arg3 = Log.createSubsession();
711 mHandler.obtainMessage(MSG_ADD_PARTICIPANT, args).sendToTarget();
712 } finally {
713 Log.endSession();
714 }
715 }
716
717 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700718 public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
719 Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
720 try {
721 SomeArgs args = SomeArgs.obtain();
722 args.arg1 = callId;
723 args.arg2 = Log.createSubsession();
724 args.argi1 = proceed ? 1 : 0;
725 mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
726 } finally {
727 Log.endSession();
728 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700729 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700730
731 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700732 public void pullExternalCall(String callId, Session.Info sessionInfo) {
733 Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
734 try {
735 SomeArgs args = SomeArgs.obtain();
736 args.arg1 = callId;
737 args.arg2 = Log.createSubsession();
738 mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
739 } finally {
740 Log.endSession();
741 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700742 }
743
744 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700745 public void sendCallEvent(String callId, String event, Bundle extras,
746 Session.Info sessionInfo) {
747 Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
748 try {
749 SomeArgs args = SomeArgs.obtain();
750 args.arg1 = callId;
751 args.arg2 = event;
752 args.arg3 = extras;
753 args.arg4 = Log.createSubsession();
754 mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
755 } finally {
756 Log.endSession();
757 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700758 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700759
760 @Override
Hall Liu73903142021-02-18 18:41:41 -0800761 public void onCallFilteringCompleted(String callId,
762 Connection.CallFilteringCompletionInfo completionInfo,
Hall Liu49cabcc2021-01-15 11:41:48 -0800763 Session.Info sessionInfo) {
764 Log.startSession(sessionInfo, SESSION_CALL_FILTERING_COMPLETED);
765 try {
766 SomeArgs args = SomeArgs.obtain();
767 args.arg1 = callId;
Hall Liu73903142021-02-18 18:41:41 -0800768 args.arg2 = completionInfo;
769 args.arg3 = Log.createSubsession();
Hall Liu49cabcc2021-01-15 11:41:48 -0800770 mHandler.obtainMessage(MSG_ON_CALL_FILTERING_COMPLETED, args).sendToTarget();
771 } finally {
772 Log.endSession();
773 }
774 }
775
776 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700777 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
778 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
779 try {
780 SomeArgs args = SomeArgs.obtain();
781 args.arg1 = callId;
782 args.arg2 = extras;
783 args.arg3 = Log.createSubsession();
784 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
785 } finally {
786 Log.endSession();
787 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700788 }
Hall Liub64ac4c2017-02-06 10:49:48 -0800789
790 @Override
791 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
792 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
793 Log.startSession(sessionInfo, SESSION_START_RTT);
794 try {
795 SomeArgs args = SomeArgs.obtain();
796 args.arg1 = callId;
797 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
798 args.arg3 = Log.createSubsession();
799 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
800 } finally {
801 Log.endSession();
802 }
803 }
804
805 @Override
806 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
807 Log.startSession(sessionInfo, SESSION_STOP_RTT);
808 try {
809 SomeArgs args = SomeArgs.obtain();
810 args.arg1 = callId;
811 args.arg2 = Log.createSubsession();
812 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
813 } finally {
814 Log.endSession();
815 }
816 }
817
818 @Override
819 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
820 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
821 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
822 try {
823 SomeArgs args = SomeArgs.obtain();
824 args.arg1 = callId;
825 if (toInCall == null || fromInCall == null) {
826 args.arg2 = null;
827 } else {
828 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
829 }
830 args.arg3 = Log.createSubsession();
831 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
832 } finally {
833 Log.endSession();
834 }
835 }
Pengquan Meng731c1a32017-11-21 18:01:13 -0800836
837 @Override
838 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
839 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
840 try {
841 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
842 } finally {
843 Log.endSession();
844 }
845 }
846
847 @Override
848 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
849 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
850 try {
851 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
852 } finally {
853 Log.endSession();
854 }
855 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700856 };
857
858 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
859 @Override
860 public void handleMessage(Message msg) {
861 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700862 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
863 SomeArgs args = (SomeArgs) msg.obj;
864 try {
865 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
866 Log.continueSession((Session) args.arg2,
867 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
868 mAdapter.addAdapter(adapter);
869 onAdapterAttached();
870 } finally {
871 args.recycle();
872 Log.endSession();
873 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700874 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700875 }
876 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
877 SomeArgs args = (SomeArgs) msg.obj;
878 try {
879 Log.continueSession((Session) args.arg2,
880 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
881 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
882 } finally {
883 args.recycle();
884 Log.endSession();
885 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700886 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700887 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700888 case MSG_CREATE_CONNECTION: {
889 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700890 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -0700891 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700892 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -0700893 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700894 final String id = (String) args.arg2;
895 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700896 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -0700897 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700898 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700899 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700900 mPreInitializationConnectionRequests.add(
901 new android.telecom.Logging.Runnable(
902 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
903 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700904 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700905 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700906 createConnection(
907 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700908 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700909 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700910 isIncoming,
911 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700912 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700913 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -0700914 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700915 createConnection(
916 connectionManagerPhoneAccount,
917 id,
918 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700919 isIncoming,
920 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700921 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700922 } finally {
923 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700924 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -0700925 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700926 break;
Ihab Awadf8b69882014-07-25 15:14:01 -0700927 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700928 case MSG_CREATE_CONNECTION_COMPLETE: {
929 SomeArgs args = (SomeArgs) msg.obj;
930 Log.continueSession((Session) args.arg2,
931 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
932 try {
933 final String id = (String) args.arg1;
934 if (!mAreAccountsInitialized) {
935 Log.d(this, "Enqueueing pre-init request %s", id);
936 mPreInitializationConnectionRequests.add(
937 new android.telecom.Logging.Runnable(
938 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
939 + ".pICR",
940 null /*lock*/) {
941 @Override
942 public void loggedRun() {
943 notifyCreateConnectionComplete(id);
944 }
945 }.prepare());
946 } else {
947 notifyCreateConnectionComplete(id);
948 }
949 } finally {
950 args.recycle();
951 Log.endSession();
952 }
953 break;
954 }
Tyler Gunn44e01912017-01-31 10:49:05 -0800955 case MSG_CREATE_CONNECTION_FAILED: {
956 SomeArgs args = (SomeArgs) msg.obj;
957 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
958 SESSION_CREATE_CONN_FAILED);
959 try {
960 final String id = (String) args.arg1;
961 final ConnectionRequest request = (ConnectionRequest) args.arg2;
962 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800963 final PhoneAccountHandle connectionMgrPhoneAccount =
964 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -0800965 if (!mAreAccountsInitialized) {
966 Log.d(this, "Enqueueing pre-init request %s", id);
967 mPreInitializationConnectionRequests.add(
968 new android.telecom.Logging.Runnable(
969 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
970 null /*lock*/) {
971 @Override
972 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800973 createConnectionFailed(connectionMgrPhoneAccount, id,
974 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800975 }
976 }.prepare());
977 } else {
978 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -0800979 createConnectionFailed(connectionMgrPhoneAccount, id, request,
980 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800981 }
982 } finally {
983 args.recycle();
984 Log.endSession();
985 }
986 break;
987 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530988 case MSG_CREATE_CONFERENCE: {
989 SomeArgs args = (SomeArgs) msg.obj;
990 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
991 try {
992 final PhoneAccountHandle connectionManagerPhoneAccount =
993 (PhoneAccountHandle) args.arg1;
994 final String id = (String) args.arg2;
995 final ConnectionRequest request = (ConnectionRequest) args.arg3;
996 final boolean isIncoming = args.argi1 == 1;
997 final boolean isUnknown = args.argi2 == 1;
998 if (!mAreAccountsInitialized) {
999 Log.d(this, "Enqueueing pre-initconference request %s", id);
1000 mPreInitializationConnectionRequests.add(
1001 new android.telecom.Logging.Runnable(
1002 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
1003 null /*lock*/) {
1004 @Override
1005 public void loggedRun() {
1006 createConference(connectionManagerPhoneAccount,
1007 id,
1008 request,
1009 isIncoming,
1010 isUnknown);
1011 }
1012 }.prepare());
1013 } else {
1014 createConference(connectionManagerPhoneAccount,
1015 id,
1016 request,
1017 isIncoming,
1018 isUnknown);
1019 }
1020 } finally {
1021 args.recycle();
1022 Log.endSession();
1023 }
1024 break;
1025 }
1026 case MSG_CREATE_CONFERENCE_COMPLETE: {
1027 SomeArgs args = (SomeArgs) msg.obj;
1028 Log.continueSession((Session) args.arg2,
1029 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
1030 try {
1031 final String id = (String) args.arg1;
1032 if (!mAreAccountsInitialized) {
1033 Log.d(this, "Enqueueing pre-init conference request %s", id);
1034 mPreInitializationConnectionRequests.add(
1035 new android.telecom.Logging.Runnable(
1036 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
1037 + ".pIConfR",
1038 null /*lock*/) {
1039 @Override
1040 public void loggedRun() {
1041 notifyCreateConferenceComplete(id);
1042 }
1043 }.prepare());
1044 } else {
1045 notifyCreateConferenceComplete(id);
1046 }
1047 } finally {
1048 args.recycle();
1049 Log.endSession();
1050 }
1051 break;
1052 }
1053 case MSG_CREATE_CONFERENCE_FAILED: {
1054 SomeArgs args = (SomeArgs) msg.obj;
1055 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1056 SESSION_CREATE_CONN_FAILED);
1057 try {
1058 final String id = (String) args.arg1;
1059 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1060 final boolean isIncoming = args.argi1 == 1;
1061 final PhoneAccountHandle connectionMgrPhoneAccount =
1062 (PhoneAccountHandle) args.arg4;
1063 if (!mAreAccountsInitialized) {
1064 Log.d(this, "Enqueueing pre-init conference request %s", id);
1065 mPreInitializationConnectionRequests.add(
1066 new android.telecom.Logging.Runnable(
1067 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
1068 + ".pIConfR",
1069 null /*lock*/) {
1070 @Override
1071 public void loggedRun() {
1072 createConferenceFailed(connectionMgrPhoneAccount, id,
1073 request, isIncoming);
1074 }
1075 }.prepare());
1076 } else {
1077 Log.i(this, "createConferenceFailed %s", id);
1078 createConferenceFailed(connectionMgrPhoneAccount, id, request,
1079 isIncoming);
1080 }
1081 } finally {
1082 args.recycle();
1083 Log.endSession();
1084 }
1085 break;
1086 }
1087
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001088 case MSG_HANDOVER_FAILED: {
1089 SomeArgs args = (SomeArgs) msg.obj;
1090 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1091 SESSION_HANDOVER_FAILED);
1092 try {
1093 final String id = (String) args.arg1;
1094 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1095 final int reason = (int) args.arg4;
1096 if (!mAreAccountsInitialized) {
1097 Log.d(this, "Enqueueing pre-init request %s", id);
1098 mPreInitializationConnectionRequests.add(
1099 new android.telecom.Logging.Runnable(
1100 SESSION_HANDLER
1101 + SESSION_HANDOVER_FAILED + ".pICR",
1102 null /*lock*/) {
1103 @Override
1104 public void loggedRun() {
1105 handoverFailed(id, request, reason);
1106 }
1107 }.prepare());
1108 } else {
1109 Log.i(this, "createConnectionFailed %s", id);
1110 handoverFailed(id, request, reason);
1111 }
1112 } finally {
1113 args.recycle();
1114 Log.endSession();
1115 }
1116 break;
1117 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001118 case MSG_ABORT: {
1119 SomeArgs args = (SomeArgs) msg.obj;
1120 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1121 try {
1122 abort((String) args.arg1);
1123 } finally {
1124 args.recycle();
1125 Log.endSession();
1126 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001127 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001128 }
1129 case MSG_ANSWER: {
1130 SomeArgs args = (SomeArgs) msg.obj;
1131 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1132 try {
1133 answer((String) args.arg1);
1134 } finally {
1135 args.recycle();
1136 Log.endSession();
1137 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001138 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001139 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001140 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001141 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001142 Log.continueSession((Session) args.arg2,
1143 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001144 try {
1145 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001146 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001147 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001148 } finally {
1149 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001150 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001151 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001152 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001153 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301154 case MSG_DEFLECT: {
1155 SomeArgs args = (SomeArgs) msg.obj;
1156 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1157 try {
1158 deflect((String) args.arg1, (Uri) args.arg2);
1159 } finally {
1160 args.recycle();
1161 Log.endSession();
1162 }
1163 break;
1164 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001165 case MSG_REJECT: {
1166 SomeArgs args = (SomeArgs) msg.obj;
1167 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1168 try {
1169 reject((String) args.arg1);
1170 } finally {
1171 args.recycle();
1172 Log.endSession();
1173 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001174 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001175 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001176 case MSG_REJECT_WITH_REASON: {
1177 SomeArgs args = (SomeArgs) msg.obj;
1178 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1179 try {
1180 reject((String) args.arg1, args.argi1);
1181 } finally {
1182 args.recycle();
1183 Log.endSession();
1184 }
1185 break;
1186 }
Bryce Lee81901682015-08-28 16:38:02 -07001187 case MSG_REJECT_WITH_MESSAGE: {
1188 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001189 Log.continueSession((Session) args.arg3,
1190 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001191 try {
1192 reject((String) args.arg1, (String) args.arg2);
1193 } finally {
1194 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001195 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001196 }
1197 break;
1198 }
Ravi Palurif4b38e72020-02-05 12:35:41 +05301199 case MSG_EXPLICIT_CALL_TRANSFER: {
1200 SomeArgs args = (SomeArgs) msg.obj;
1201 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_TRANSFER);
1202 try {
1203 final boolean isConfirmationRequired = args.argi1 == 1;
1204 transfer((String) args.arg1, (Uri) args.arg2, isConfirmationRequired);
1205 } finally {
1206 args.recycle();
1207 Log.endSession();
1208 }
1209 break;
1210 }
1211 case MSG_EXPLICIT_CALL_TRANSFER_CONSULTATIVE: {
1212 SomeArgs args = (SomeArgs) msg.obj;
1213 Log.continueSession(
1214 (Session) args.arg3, SESSION_HANDLER + SESSION_CONSULTATIVE_TRANSFER);
1215 try {
1216 consultativeTransfer((String) args.arg1, (String) args.arg2);
1217 } finally {
1218 args.recycle();
1219 Log.endSession();
1220 }
1221 break;
1222 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001223 case MSG_DISCONNECT: {
1224 SomeArgs args = (SomeArgs) msg.obj;
1225 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1226 try {
1227 disconnect((String) args.arg1);
1228 } finally {
1229 args.recycle();
1230 Log.endSession();
1231 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001232 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001233 }
1234 case MSG_SILENCE: {
1235 SomeArgs args = (SomeArgs) msg.obj;
1236 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1237 try {
1238 silence((String) args.arg1);
1239 } finally {
1240 args.recycle();
1241 Log.endSession();
1242 }
Bryce Leecac50772015-11-17 15:13:29 -08001243 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001244 }
1245 case MSG_HOLD: {
1246 SomeArgs args = (SomeArgs) msg.obj;
1247 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1248 try {
1249 hold((String) args.arg1);
1250 } finally {
1251 args.recycle();
1252 Log.endSession();
1253 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001254 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001255 }
1256 case MSG_UNHOLD: {
1257 SomeArgs args = (SomeArgs) msg.obj;
1258 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1259 try {
1260 unhold((String) args.arg1);
1261 } finally {
1262 args.recycle();
1263 Log.endSession();
1264 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001265 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001266 }
Yorke Lee4af59352015-05-13 14:14:54 -07001267 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001268 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001269 Log.continueSession((Session) args.arg3,
1270 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001271 try {
1272 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001273 CallAudioState audioState = (CallAudioState) args.arg2;
1274 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001275 } finally {
1276 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001277 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001278 }
1279 break;
1280 }
Grace Jiae99fde92021-01-19 14:58:01 -08001281 case MSG_ON_USING_ALTERNATIVE_UI: {
1282 SomeArgs args = (SomeArgs) msg.obj;
1283 Log.continueSession((Session) args.arg3,
1284 SESSION_HANDLER + SESSION_USING_ALTERNATIVE_UI);
1285 try {
1286 String callId = (String) args.arg1;
1287 boolean isUsingAlternativeUi = (boolean) args.arg2;
1288 onUsingAlternativeUi(callId, isUsingAlternativeUi);
1289 } finally {
1290 args.recycle();
1291 Log.endSession();
1292 }
1293 break;
1294 }
1295 case MSG_ON_TRACKED_BY_NON_UI_SERVICE: {
1296 SomeArgs args = (SomeArgs) msg.obj;
1297 Log.continueSession((Session) args.arg3,
1298 SESSION_HANDLER + SESSION_TRACKED_BY_NON_UI_SERVICE);
1299 try {
1300 String callId = (String) args.arg1;
1301 boolean isTracked = (boolean) args.arg2;
1302 onTrackedByNonUiService(callId, isTracked);
1303 } finally {
1304 args.recycle();
1305 Log.endSession();
1306 }
1307 break;
1308 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001309 case MSG_PLAY_DTMF_TONE: {
1310 SomeArgs args = (SomeArgs) msg.obj;
1311 try {
1312 Log.continueSession((Session) args.arg3,
1313 SESSION_HANDLER + SESSION_PLAY_DTMF);
1314 playDtmfTone((String) args.arg2, (char) args.arg1);
1315 } finally {
1316 args.recycle();
1317 Log.endSession();
1318 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001319 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001320 }
1321 case MSG_STOP_DTMF_TONE: {
1322 SomeArgs args = (SomeArgs) msg.obj;
1323 try {
1324 Log.continueSession((Session) args.arg2,
1325 SESSION_HANDLER + SESSION_STOP_DTMF);
1326 stopDtmfTone((String) args.arg1);
1327 } finally {
1328 args.recycle();
1329 Log.endSession();
1330 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001331 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001332 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001333 case MSG_CONFERENCE: {
1334 SomeArgs args = (SomeArgs) msg.obj;
1335 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001336 Log.continueSession((Session) args.arg3,
1337 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001338 String callId1 = (String) args.arg1;
1339 String callId2 = (String) args.arg2;
1340 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001341 } finally {
1342 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001343 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001344 }
1345 break;
1346 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001347 case MSG_SPLIT_FROM_CONFERENCE: {
1348 SomeArgs args = (SomeArgs) msg.obj;
1349 try {
1350 Log.continueSession((Session) args.arg2,
1351 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1352 splitFromConference((String) args.arg1);
1353 } finally {
1354 args.recycle();
1355 Log.endSession();
1356 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001357 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001358 }
1359 case MSG_MERGE_CONFERENCE: {
1360 SomeArgs args = (SomeArgs) msg.obj;
1361 try {
1362 Log.continueSession((Session) args.arg2,
1363 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1364 mergeConference((String) args.arg1);
1365 } finally {
1366 args.recycle();
1367 Log.endSession();
1368 }
Santos Cordona4868042014-09-04 17:39:22 -07001369 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001370 }
1371 case MSG_SWAP_CONFERENCE: {
1372 SomeArgs args = (SomeArgs) msg.obj;
1373 try {
1374 Log.continueSession((Session) args.arg2,
1375 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1376 swapConference((String) args.arg1);
1377 } finally {
1378 args.recycle();
1379 Log.endSession();
1380 }
Santos Cordona4868042014-09-04 17:39:22 -07001381 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001382 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301383 case MSG_ADD_PARTICIPANT: {
1384 SomeArgs args = (SomeArgs) msg.obj;
1385 try {
1386 Log.continueSession((Session) args.arg3,
1387 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1388 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1389 } finally {
1390 args.recycle();
1391 Log.endSession();
1392 }
1393 break;
1394 }
1395
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001396 case MSG_ON_POST_DIAL_CONTINUE: {
1397 SomeArgs args = (SomeArgs) msg.obj;
1398 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001399 Log.continueSession((Session) args.arg2,
1400 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001401 String callId = (String) args.arg1;
1402 boolean proceed = (args.argi1 == 1);
1403 onPostDialContinue(callId, proceed);
1404 } finally {
1405 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001406 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001407 }
1408 break;
1409 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001410 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001411 SomeArgs args = (SomeArgs) msg.obj;
1412 try {
1413 Log.continueSession((Session) args.arg2,
1414 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1415 pullExternalCall((String) args.arg1);
1416 } finally {
1417 args.recycle();
1418 Log.endSession();
1419 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001420 break;
1421 }
1422 case MSG_SEND_CALL_EVENT: {
1423 SomeArgs args = (SomeArgs) msg.obj;
1424 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001425 Log.continueSession((Session) args.arg4,
1426 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001427 String callId = (String) args.arg1;
1428 String event = (String) args.arg2;
1429 Bundle extras = (Bundle) args.arg3;
1430 sendCallEvent(callId, event, extras);
1431 } finally {
1432 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001433 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001434 }
1435 break;
1436 }
Hall Liu49cabcc2021-01-15 11:41:48 -08001437 case MSG_ON_CALL_FILTERING_COMPLETED: {
1438 SomeArgs args = (SomeArgs) msg.obj;
1439 try {
Hall Liu73903142021-02-18 18:41:41 -08001440 Log.continueSession((Session) args.arg3,
Hall Liu49cabcc2021-01-15 11:41:48 -08001441 SESSION_HANDLER + SESSION_CALL_FILTERING_COMPLETED);
1442 String callId = (String) args.arg1;
Hall Liu73903142021-02-18 18:41:41 -08001443 Connection.CallFilteringCompletionInfo completionInfo =
1444 (Connection.CallFilteringCompletionInfo) args.arg2;
1445 onCallFilteringCompleted(callId, completionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08001446 } finally {
1447 args.recycle();
1448 Log.endSession();
1449 }
1450 break;
1451 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001452 case MSG_HANDOVER_COMPLETE: {
1453 SomeArgs args = (SomeArgs) msg.obj;
1454 try {
1455 Log.continueSession((Session) args.arg2,
1456 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1457 String callId = (String) args.arg1;
1458 notifyHandoverComplete(callId);
1459 } finally {
1460 args.recycle();
1461 Log.endSession();
1462 }
1463 break;
1464 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001465 case MSG_ON_EXTRAS_CHANGED: {
1466 SomeArgs args = (SomeArgs) msg.obj;
1467 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001468 Log.continueSession((Session) args.arg3,
1469 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001470 String callId = (String) args.arg1;
1471 Bundle extras = (Bundle) args.arg2;
1472 handleExtrasChanged(callId, extras);
1473 } finally {
1474 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001475 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001476 }
1477 break;
1478 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001479 case MSG_ON_START_RTT: {
1480 SomeArgs args = (SomeArgs) msg.obj;
1481 try {
1482 Log.continueSession((Session) args.arg3,
1483 SESSION_HANDLER + SESSION_START_RTT);
1484 String callId = (String) args.arg1;
1485 Connection.RttTextStream rttTextStream =
1486 (Connection.RttTextStream) args.arg2;
1487 startRtt(callId, rttTextStream);
1488 } finally {
1489 args.recycle();
1490 Log.endSession();
1491 }
1492 break;
1493 }
1494 case MSG_ON_STOP_RTT: {
1495 SomeArgs args = (SomeArgs) msg.obj;
1496 try {
1497 Log.continueSession((Session) args.arg2,
1498 SESSION_HANDLER + SESSION_STOP_RTT);
1499 String callId = (String) args.arg1;
1500 stopRtt(callId);
1501 } finally {
1502 args.recycle();
1503 Log.endSession();
1504 }
1505 break;
1506 }
1507 case MSG_RTT_UPGRADE_RESPONSE: {
1508 SomeArgs args = (SomeArgs) msg.obj;
1509 try {
1510 Log.continueSession((Session) args.arg3,
1511 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1512 String callId = (String) args.arg1;
1513 Connection.RttTextStream rttTextStream =
1514 (Connection.RttTextStream) args.arg2;
1515 handleRttUpgradeResponse(callId, rttTextStream);
1516 } finally {
1517 args.recycle();
1518 Log.endSession();
1519 }
1520 break;
1521 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001522 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1523 onConnectionServiceFocusGained();
1524 break;
1525 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1526 onConnectionServiceFocusLost();
1527 break;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001528 default:
1529 break;
1530 }
1531 }
1532 };
1533
Santos Cordon823fd3c2014-08-07 18:35:18 -07001534 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1535 @Override
1536 public void onStateChanged(Conference conference, int oldState, int newState) {
1537 String id = mIdByConference.get(conference);
1538 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301539 case Connection.STATE_RINGING:
1540 mAdapter.setRinging(id);
1541 break;
1542 case Connection.STATE_DIALING:
1543 mAdapter.setDialing(id);
1544 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001545 case Connection.STATE_ACTIVE:
1546 mAdapter.setActive(id);
1547 break;
1548 case Connection.STATE_HOLDING:
1549 mAdapter.setOnHold(id);
1550 break;
1551 case Connection.STATE_DISCONNECTED:
1552 // handled by onDisconnected
1553 break;
1554 }
1555 }
1556
1557 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001558 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001559 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001560 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001561 }
1562
1563 @Override
1564 public void onConnectionAdded(Conference conference, Connection connection) {
1565 }
1566
1567 @Override
1568 public void onConnectionRemoved(Conference conference, Connection connection) {
1569 }
1570
1571 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001572 public void onConferenceableConnectionsChanged(
1573 Conference conference, List<Connection> conferenceableConnections) {
1574 mAdapter.setConferenceableConnections(
1575 mIdByConference.get(conference),
1576 createConnectionIdList(conferenceableConnections));
1577 }
1578
1579 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001580 public void onDestroyed(Conference conference) {
1581 removeConference(conference);
1582 }
1583
1584 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001585 public void onConnectionCapabilitiesChanged(
1586 Conference conference,
1587 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001588 String id = mIdByConference.get(conference);
1589 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001590 Connection.capabilitiesToString(connectionCapabilities));
1591 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001592 }
Rekha Kumar07366812015-03-24 16:42:31 -07001593
1594 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001595 public void onConnectionPropertiesChanged(
1596 Conference conference,
1597 int connectionProperties) {
1598 String id = mIdByConference.get(conference);
1599 Log.d(this, "call capabilities: conference: %s",
1600 Connection.propertiesToString(connectionProperties));
1601 mAdapter.setConnectionProperties(id, connectionProperties);
1602 }
1603
1604 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001605 public void onVideoStateChanged(Conference c, int videoState) {
1606 String id = mIdByConference.get(c);
1607 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1608 mAdapter.setVideoState(id, videoState);
1609 }
1610
1611 @Override
1612 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1613 String id = mIdByConference.get(c);
1614 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1615 videoProvider);
1616 mAdapter.setVideoProvider(id, videoProvider);
1617 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001618
1619 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001620 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1621 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001622 if (id != null) {
1623 mAdapter.setStatusHints(id, statusHints);
1624 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001625 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001626
1627 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001628 public void onExtrasChanged(Conference c, Bundle extras) {
1629 String id = mIdByConference.get(c);
1630 if (id != null) {
1631 mAdapter.putExtras(id, extras);
1632 }
1633 }
1634
1635 @Override
1636 public void onExtrasRemoved(Conference c, List<String> keys) {
1637 String id = mIdByConference.get(c);
1638 if (id != null) {
1639 mAdapter.removeExtras(id, keys);
1640 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001641 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001642
1643 @Override
1644 public void onConferenceStateChanged(Conference c, boolean isConference) {
1645 String id = mIdByConference.get(c);
1646 if (id != null) {
1647 mAdapter.setConferenceState(id, isConference);
1648 }
1649 }
1650
1651 @Override
Brad Ebingere0c12f42020-04-08 16:25:12 -07001652 public void onCallDirectionChanged(Conference c, int direction) {
1653 String id = mIdByConference.get(c);
1654 if (id != null) {
1655 mAdapter.setCallDirection(id, direction);
1656 }
1657 }
1658
1659 @Override
Tyler Gunn68a73a42018-10-03 15:38:57 -07001660 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1661 String id = mIdByConference.get(c);
1662 if (id != null) {
1663 mAdapter.setAddress(id, newAddress, presentation);
1664 }
1665 }
1666
1667 @Override
1668 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1669 int presentation) {
1670 String id = mIdByConference.get(c);
1671 if (id != null) {
1672 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1673 }
1674 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001675
1676 @Override
1677 public void onConnectionEvent(Conference c, String event, Bundle extras) {
1678 String id = mIdByConference.get(c);
1679 if (id != null) {
1680 mAdapter.onConnectionEvent(id, event, extras);
1681 }
1682 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301683
1684 @Override
1685 public void onRingbackRequested(Conference c, boolean ringback) {
1686 String id = mIdByConference.get(c);
1687 Log.d(this, "Adapter conference onRingback %b", ringback);
1688 mAdapter.setRingbackRequested(id, ringback);
1689 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001690 };
1691
Ihab Awad542e0ea2014-05-16 10:22:16 -07001692 private final Connection.Listener mConnectionListener = new Connection.Listener() {
1693 @Override
1694 public void onStateChanged(Connection c, int state) {
1695 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07001696 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001697 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001698 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001699 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001700 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001701 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001702 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001703 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001704 case Connection.STATE_PULLING_CALL:
1705 mAdapter.setPulling(id);
1706 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001707 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001708 // Handled in onDisconnected()
1709 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001710 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001711 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001712 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001713 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001714 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07001715 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001716 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001717 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001718 break;
1719 }
1720 }
1721
1722 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001723 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07001724 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07001725 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001726 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001727 }
1728
1729 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07001730 public void onVideoStateChanged(Connection c, int videoState) {
1731 String id = mIdByConnection.get(c);
1732 Log.d(this, "Adapter set video state %d", videoState);
1733 mAdapter.setVideoState(id, videoState);
1734 }
1735
1736 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001737 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001738 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001739 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07001740 }
1741
1742 @Override
1743 public void onCallerDisplayNameChanged(
1744 Connection c, String callerDisplayName, int presentation) {
1745 String id = mIdByConnection.get(c);
1746 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001747 }
1748
1749 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07001750 public void onDestroyed(Connection c) {
1751 removeConnection(c);
1752 }
Ihab Awadf8358972014-05-28 16:46:42 -07001753
1754 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001755 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07001756 String id = mIdByConnection.get(c);
1757 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001758 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001759 }
1760
1761 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001762 public void onPostDialChar(Connection c, char nextChar) {
1763 String id = mIdByConnection.get(c);
1764 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
1765 mAdapter.onPostDialChar(id, nextChar);
1766 }
1767
1768 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001769 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07001770 String id = mIdByConnection.get(c);
1771 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07001772 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07001773 }
Santos Cordonb6939982014-06-04 20:20:58 -07001774
1775 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001776 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07001777 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001778 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001779 Connection.capabilitiesToString(capabilities));
1780 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07001781 }
1782
Santos Cordonb6939982014-06-04 20:20:58 -07001783 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001784 public void onConnectionPropertiesChanged(Connection c, int properties) {
1785 String id = mIdByConnection.get(c);
1786 Log.d(this, "properties: parcelableconnection: %s",
1787 Connection.propertiesToString(properties));
1788 mAdapter.setConnectionProperties(id, properties);
1789 }
1790
1791 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001792 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001793 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07001794 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1795 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001796 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001797 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001798
1799 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001800 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001801 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001802 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001803 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001804
1805 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001806 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001807 String id = mIdByConnection.get(c);
1808 mAdapter.setStatusHints(id, statusHints);
1809 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001810
1811 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001812 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001813 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001814 mAdapter.setConferenceableConnections(
1815 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001816 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001817 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001818
1819 @Override
1820 public void onConferenceChanged(Connection connection, Conference conference) {
1821 String id = mIdByConnection.get(connection);
1822 if (id != null) {
1823 String conferenceId = null;
1824 if (conference != null) {
1825 conferenceId = mIdByConference.get(conference);
1826 }
1827 mAdapter.setIsConferenced(id, conferenceId);
1828 }
1829 }
Anthony Lee17455a32015-04-24 15:25:29 -07001830
1831 @Override
1832 public void onConferenceMergeFailed(Connection connection) {
1833 String id = mIdByConnection.get(connection);
1834 if (id != null) {
1835 mAdapter.onConferenceMergeFailed(id);
1836 }
1837 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001838
1839 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001840 public void onExtrasChanged(Connection c, Bundle extras) {
1841 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001842 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07001843 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001844 }
1845 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001846
Tyler Gunnf5035432017-01-09 09:43:12 -08001847 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001848 public void onExtrasRemoved(Connection c, List<String> keys) {
1849 String id = mIdByConnection.get(c);
1850 if (id != null) {
1851 mAdapter.removeExtras(id, keys);
1852 }
1853 }
1854
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001855 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001856 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001857 String id = mIdByConnection.get(connection);
1858 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001859 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001860 }
1861 }
Tyler Gunnf5035432017-01-09 09:43:12 -08001862
1863 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08001864 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001865 String id = mIdByConnection.get(c);
1866 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08001867 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08001868 }
1869 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001870
1871 @Override
1872 public void onRttInitiationSuccess(Connection c) {
1873 String id = mIdByConnection.get(c);
1874 if (id != null) {
1875 mAdapter.onRttInitiationSuccess(id);
1876 }
1877 }
1878
1879 @Override
1880 public void onRttInitiationFailure(Connection c, int reason) {
1881 String id = mIdByConnection.get(c);
1882 if (id != null) {
1883 mAdapter.onRttInitiationFailure(id, reason);
1884 }
1885 }
1886
1887 @Override
1888 public void onRttSessionRemotelyTerminated(Connection c) {
1889 String id = mIdByConnection.get(c);
1890 if (id != null) {
1891 mAdapter.onRttSessionRemotelyTerminated(id);
1892 }
1893 }
1894
1895 @Override
1896 public void onRemoteRttRequest(Connection c) {
1897 String id = mIdByConnection.get(c);
1898 if (id != null) {
1899 mAdapter.onRemoteRttRequest(id);
1900 }
1901 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05301902
1903 @Override
1904 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
1905 String id = mIdByConnection.get(c);
1906 if (id != null) {
1907 mAdapter.onPhoneAccountChanged(id, pHandle);
1908 }
1909 }
Mengjun Leng25707742017-07-04 11:10:37 +08001910
1911 public void onConnectionTimeReset(Connection c) {
1912 String id = mIdByConnection.get(c);
1913 if (id != null) {
1914 mAdapter.resetConnectionTime(id);
1915 }
1916 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001917 };
1918
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001919 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07001920 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001921 public final IBinder onBind(Intent intent) {
1922 return mBinder;
1923 }
1924
Santos Cordon29f2f2e2014-09-11 19:50:24 -07001925 /** {@inheritDoc} */
1926 @Override
1927 public boolean onUnbind(Intent intent) {
1928 endAllConnections();
1929 return super.onUnbind(intent);
1930 }
1931
Ravi Paluri80aa2142019-12-02 11:57:37 +05301932
1933 /**
1934 * This can be used by telecom to either create a new outgoing conference call or attach
1935 * to an existing incoming conference call. In either case, telecom will cycle through a
1936 * set of services and call createConference until a connection service cancels the process
1937 * or completes it successfully.
1938 */
1939 private void createConference(
1940 final PhoneAccountHandle callManagerAccount,
1941 final String callId,
1942 final ConnectionRequest request,
1943 boolean isIncoming,
1944 boolean isUnknown) {
1945
1946 Conference conference = null;
1947 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
1948 : onCreateOutgoingConference(callManagerAccount, request);
1949
1950 Log.d(this, "createConference, conference: %s", conference);
1951 if (conference == null) {
1952 Log.i(this, "createConference, implementation returned null conference.");
1953 conference = Conference.createFailedConference(
1954 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
1955 request.getAccountHandle());
1956 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001957
1958 Bundle extras = request.getExtras();
1959 Bundle newExtras = new Bundle();
1960 newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
1961 if (extras != null) {
1962 // If the request originated from a remote connection service, we will add some
1963 // tracking information that Telecom can use to keep informed of which package
1964 // made the remote request, and which remote connection service was used.
1965 if (extras.containsKey(Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
1966 newExtras.putString(
1967 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
1968 extras.getString(
1969 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME));
1970 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
1971 request.getAccountHandle());
1972 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301973 }
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07001974 conference.putExtras(newExtras);
1975
Ravi Paluri80aa2142019-12-02 11:57:37 +05301976 mConferenceById.put(callId, conference);
1977 mIdByConference.put(conference, callId);
Tyler Gunn460360d2020-07-29 10:21:45 -07001978
Ravi Paluri80aa2142019-12-02 11:57:37 +05301979 conference.addListener(mConferenceListener);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07001980 ParcelableConference parcelableConference = new ParcelableConference.Builder(
1981 request.getAccountHandle(), conference.getState())
1982 .setConnectionCapabilities(conference.getConnectionCapabilities())
1983 .setConnectionProperties(conference.getConnectionProperties())
1984 .setVideoAttributes(conference.getVideoProvider() == null
1985 ? null : conference.getVideoProvider().getInterface(),
1986 conference.getVideoState())
1987 .setConnectTimeMillis(conference.getConnectTimeMillis(),
1988 conference.getConnectionStartElapsedRealtimeMillis())
1989 .setStatusHints(conference.getStatusHints())
1990 .setExtras(conference.getExtras())
1991 .setAddress(conference.getAddress(), conference.getAddressPresentation())
1992 .setCallerDisplayName(conference.getCallerDisplayName(),
1993 conference.getCallerDisplayNamePresentation())
1994 .setDisconnectCause(conference.getDisconnectCause())
1995 .setRingbackRequested(conference.isRingbackRequested())
1996 .build();
Ravi Paluri80aa2142019-12-02 11:57:37 +05301997 if (conference.getState() != Connection.STATE_DISCONNECTED) {
1998 conference.setTelecomCallId(callId);
1999 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
2000 mAdapter.setVideoState(callId, conference.getVideoState());
2001 onConferenceAdded(conference);
2002 }
2003
2004 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
2005 mAdapter.handleCreateConferenceComplete(
2006 callId,
2007 request,
2008 parcelableConference);
2009 }
2010
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002011 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07002012 * This can be used by telecom to either create a new outgoing call or attach to an existing
2013 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002014 * createConnection util a connection service cancels the process or completes it successfully.
2015 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002016 private void createConnection(
2017 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002018 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07002019 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07002020 boolean isIncoming,
2021 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002022 boolean isLegacyHandover = request.getExtras() != null &&
2023 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
2024 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
2025 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Grace Jiae99fde92021-01-19 14:58:01 -08002026 boolean addSelfManaged = request.getExtras() != null && request.getExtras().getBoolean(
Grace Jia8b22bb42021-02-02 15:37:32 -08002027 PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
Grace Jiae99fde92021-01-19 14:58:01 -08002028 Log.i(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, "
2029 + "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b, "
2030 + " addSelfManaged: %b", callManagerAccount, callId, request, isIncoming,
2031 isUnknown, isLegacyHandover, isHandover, addSelfManaged);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002032
Sanket Padawee29a2662017-12-01 13:59:27 -08002033 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002034 if (isHandover) {
2035 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
2036 ? (PhoneAccountHandle) request.getExtras().getParcelable(
2037 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08002038 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002039 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002040 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002041 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08002042 }
2043 } else {
2044 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
2045 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
2046 : onCreateOutgoingConnection(callManagerAccount, request);
2047 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002048 Log.d(this, "createConnection, connection: %s", connection);
2049 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002050 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002051 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08002052 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Tyler Gunnc59fd0c2020-04-17 14:03:35 -07002053 } else {
2054 try {
2055 Bundle extras = request.getExtras();
2056 if (extras != null) {
2057 // If the request originated from a remote connection service, we will add some
2058 // tracking information that Telecom can use to keep informed of which package
2059 // made the remote request, and which remote connection service was used.
2060 if (extras.containsKey(
2061 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME)) {
2062 Bundle newExtras = new Bundle();
2063 newExtras.putString(
2064 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME,
2065 extras.getString(
2066 Connection.EXTRA_REMOTE_CONNECTION_ORIGINATING_PACKAGE_NAME
2067 ));
2068 newExtras.putParcelable(Connection.EXTRA_REMOTE_PHONE_ACCOUNT_HANDLE,
2069 request.getAccountHandle());
2070 connection.putExtras(newExtras);
2071 }
2072 }
2073 } catch (UnsupportedOperationException ose) {
2074 // Do nothing; if the ConnectionService reported a failure it will be an instance
2075 // of an immutable Connection which we cannot edit, so we're out of luck.
2076 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002077 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002078
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002079 boolean isSelfManaged =
2080 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
2081 == Connection.PROPERTY_SELF_MANAGED;
2082 // Self-managed Connections should always use voip audio mode; we default here so that the
2083 // local state within the ConnectionService matches the default we assume in Telecom.
2084 if (isSelfManaged) {
2085 connection.setAudioModeIsVoip(true);
2086 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002087 connection.setTelecomCallId(callId);
Sungjae7f4137452020-09-16 17:01:54 +09002088 PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
2089 ? request.getAccountHandle() : connection.getPhoneAccountHandle();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002090 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Sungjae7f4137452020-09-16 17:01:54 +09002091 addConnection(phoneAccountHandle, callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07002092 }
2093
Andrew Lee100e2932014-09-08 15:34:24 -07002094 Uri address = connection.getAddress();
2095 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07002096 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002097 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002098 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07002099 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
2100 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07002101
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002102 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07002103 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002104 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07002105 request,
2106 new ParcelableConnection(
Sungjae7f4137452020-09-16 17:01:54 +09002107 phoneAccountHandle,
Evan Charltonbf11f982014-07-20 22:06:28 -07002108 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002109 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002110 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002111 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07002112 connection.getAddress(),
2113 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07002114 connection.getCallerDisplayName(),
2115 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07002116 connection.getVideoProvider() == null ?
2117 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002118 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07002119 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07002120 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002121 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002122 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07002123 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002124 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002125 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002126 connection.getExtras(),
2127 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08002128
Tyler Gunnf2e08b42018-05-24 10:44:44 -07002129 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002130 // Tell ConnectionService to show its incoming call UX.
2131 connection.onShowIncomingCallUi();
2132 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002133 if (isUnknown) {
2134 triggerConferenceRecalculate();
2135 }
Evan Charltonbf11f982014-07-20 22:06:28 -07002136 }
2137
Tyler Gunn159f35c2017-03-02 09:28:37 -08002138 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
2139 final String callId, final ConnectionRequest request,
2140 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08002141
2142 Log.i(this, "createConnectionFailed %s", callId);
2143 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002144 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002145 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08002146 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08002147 }
2148 }
2149
Ravi Paluri80aa2142019-12-02 11:57:37 +05302150 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
2151 final String callId, final ConnectionRequest request,
2152 boolean isIncoming) {
2153
2154 Log.i(this, "createConferenceFailed %s", callId);
2155 if (isIncoming) {
2156 onCreateIncomingConferenceFailed(callManagerAccount, request);
2157 } else {
2158 onCreateOutgoingConferenceFailed(callManagerAccount, request);
2159 }
2160 }
2161
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08002162 private void handoverFailed(final String callId, final ConnectionRequest request,
2163 int reason) {
2164
2165 Log.i(this, "handoverFailed %s", callId);
2166 onHandoverFailed(request, reason);
2167 }
2168
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002169 /**
2170 * Called by Telecom when the creation of a new Connection has completed and it is now added
2171 * to Telecom.
2172 * @param callId The ID of the connection.
2173 */
2174 private void notifyCreateConnectionComplete(final String callId) {
2175 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07002176 if (callId == null) {
2177 // This could happen if the connection fails quickly and is removed from the
2178 // ConnectionService before Telecom sends the create connection complete callback.
2179 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
2180 return;
2181 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002182 onCreateConnectionComplete(findConnectionForAction(callId,
2183 "notifyCreateConnectionComplete"));
2184 }
2185
Ravi Paluri80aa2142019-12-02 11:57:37 +05302186 /**
2187 * Called by Telecom when the creation of a new Conference has completed and it is now added
2188 * to Telecom.
2189 * @param callId The ID of the connection.
2190 */
2191 private void notifyCreateConferenceComplete(final String callId) {
2192 Log.i(this, "notifyCreateConferenceComplete %s", callId);
2193 if (callId == null) {
2194 // This could happen if the conference fails quickly and is removed from the
2195 // ConnectionService before Telecom sends the create conference complete callback.
2196 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
2197 return;
2198 }
2199 onCreateConferenceComplete(findConferenceForAction(callId,
2200 "notifyCreateConferenceComplete"));
2201 }
2202
2203
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002204 private void abort(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002205 Log.i(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002206 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002207 }
2208
Tyler Gunnbe74de02014-08-29 14:51:48 -07002209 private void answerVideo(String callId, int videoState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002210 Log.i(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302211 if (mConnectionById.containsKey(callId)) {
2212 findConnectionForAction(callId, "answer").onAnswer(videoState);
2213 } else {
2214 findConferenceForAction(callId, "answer").onAnswer(videoState);
2215 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002216 }
2217
Tyler Gunnbe74de02014-08-29 14:51:48 -07002218 private void answer(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002219 Log.i(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302220 if (mConnectionById.containsKey(callId)) {
2221 findConnectionForAction(callId, "answer").onAnswer();
2222 } else {
2223 findConferenceForAction(callId, "answer").onAnswer();
2224 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002225 }
2226
Pooja Jaind34698d2017-12-28 14:15:31 +05302227 private void deflect(String callId, Uri address) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002228 Log.i(this, "deflect %s", callId);
Pooja Jaind34698d2017-12-28 14:15:31 +05302229 findConnectionForAction(callId, "deflect").onDeflect(address);
2230 }
2231
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002232 private void reject(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002233 Log.i(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302234 if (mConnectionById.containsKey(callId)) {
2235 findConnectionForAction(callId, "reject").onReject();
2236 } else {
2237 findConferenceForAction(callId, "reject").onReject();
2238 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002239 }
2240
Bryce Lee81901682015-08-28 16:38:02 -07002241 private void reject(String callId, String rejectWithMessage) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002242 Log.i(this, "reject %s with message", callId);
Bryce Lee81901682015-08-28 16:38:02 -07002243 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2244 }
2245
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002246 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002247 Log.i(this, "reject %s with reason %d", callId, rejectReason);
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002248 findConnectionForAction(callId, "reject").onReject(rejectReason);
2249 }
2250
Ravi Palurif4b38e72020-02-05 12:35:41 +05302251 private void transfer(String callId, Uri number, boolean isConfirmationRequired) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002252 Log.i(this, "transfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302253 findConnectionForAction(callId, "transfer").onTransfer(number, isConfirmationRequired);
2254 }
2255
2256 private void consultativeTransfer(String callId, String otherCallId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002257 Log.i(this, "consultativeTransfer %s", callId);
Ravi Palurif4b38e72020-02-05 12:35:41 +05302258 Connection connection1 = findConnectionForAction(callId, "consultativeTransfer");
2259 Connection connection2 = findConnectionForAction(otherCallId, " consultativeTransfer");
2260 connection1.onTransfer(connection2);
2261 }
2262
Bryce Leecac50772015-11-17 15:13:29 -08002263 private void silence(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002264 Log.i(this, "silence %s", callId);
Bryce Leecac50772015-11-17 15:13:29 -08002265 findConnectionForAction(callId, "silence").onSilence();
2266 }
2267
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002268 private void disconnect(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002269 Log.i(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002270 if (mConnectionById.containsKey(callId)) {
2271 findConnectionForAction(callId, "disconnect").onDisconnect();
2272 } else {
2273 findConferenceForAction(callId, "disconnect").onDisconnect();
2274 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002275 }
2276
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002277 private void hold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002278 Log.i(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002279 if (mConnectionById.containsKey(callId)) {
2280 findConnectionForAction(callId, "hold").onHold();
2281 } else {
2282 findConferenceForAction(callId, "hold").onHold();
2283 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002284 }
2285
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002286 private void unhold(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002287 Log.i(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002288 if (mConnectionById.containsKey(callId)) {
2289 findConnectionForAction(callId, "unhold").onUnhold();
2290 } else {
2291 findConferenceForAction(callId, "unhold").onUnhold();
2292 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002293 }
2294
Yorke Lee4af59352015-05-13 14:14:54 -07002295 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002296 Log.i(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002297 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002298 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2299 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002300 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002301 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2302 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002303 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002304 }
2305
Grace Jiae99fde92021-01-19 14:58:01 -08002306 private void onUsingAlternativeUi(String callId, boolean isUsingAlternativeUi) {
2307 Log.i(this, "onUsingAlternativeUi %s %s", callId, isUsingAlternativeUi);
2308 if (mConnectionById.containsKey(callId)) {
2309 findConnectionForAction(callId, "onUsingAlternativeUi")
2310 .onUsingAlternativeUi(isUsingAlternativeUi);
2311 }
2312 }
2313
2314 private void onTrackedByNonUiService(String callId, boolean isTracked) {
2315 Log.i(this, "onTrackedByNonUiService %s %s", callId, isTracked);
2316 if (mConnectionById.containsKey(callId)) {
2317 findConnectionForAction(callId, "onTrackedByNonUiService")
2318 .onTrackedByNonUiService(isTracked);
2319 }
2320 }
2321
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002322 private void playDtmfTone(String callId, char digit) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002323 Log.i(this, "playDtmfTone %s %c", callId, digit);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002324 if (mConnectionById.containsKey(callId)) {
2325 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2326 } else {
2327 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2328 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002329 }
2330
2331 private void stopDtmfTone(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002332 Log.i(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002333 if (mConnectionById.containsKey(callId)) {
2334 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2335 } else {
2336 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2337 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002338 }
2339
Santos Cordon823fd3c2014-08-07 18:35:18 -07002340 private void conference(String callId1, String callId2) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002341 Log.i(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002342
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002343 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002344 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002345 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002346 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002347 conference2 = findConferenceForAction(callId2, "conference");
2348 if (conference2 == getNullConference()) {
2349 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2350 callId2);
2351 return;
2352 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002353 }
Santos Cordonb6939982014-06-04 20:20:58 -07002354
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002355 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002356 Connection connection1 = findConnectionForAction(callId1, "conference");
2357 if (connection1 == getNullConnection()) {
2358 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2359 if (conference1 == getNullConference()) {
2360 Log.w(this,
2361 "Connection1 or Conference1 missing in conference request %s.",
2362 callId1);
2363 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002364 // Call 1 is a conference.
2365 if (connection2 != getNullConnection()) {
2366 // Call 2 is a connection so merge via call 1 (conference).
2367 conference1.onMerge(connection2);
2368 } else {
2369 // Call 2 is ALSO a conference; this should never happen.
2370 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2371 "merge two conferences.");
2372 return;
2373 }
Ihab Awad50e35062014-09-30 09:17:03 -07002374 }
2375 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002376 // Call 1 is a connection.
2377 if (conference2 != getNullConference()) {
2378 // Call 2 is a conference, so merge via call 2.
2379 conference2.onMerge(connection1);
2380 } else {
2381 // Call 2 is a connection, so merge together.
2382 onConference(connection1, connection2);
2383 }
Ihab Awad50e35062014-09-30 09:17:03 -07002384 }
Santos Cordon980acb92014-05-31 10:31:19 -07002385 }
2386
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002387 private void splitFromConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002388 Log.i(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002389
2390 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002391 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002392 Log.w(this, "Connection missing in conference request %s.", callId);
2393 return;
2394 }
2395
Santos Cordon0159ac02014-08-21 14:28:11 -07002396 Conference conference = connection.getConference();
2397 if (conference != null) {
2398 conference.onSeparate(connection);
2399 }
Santos Cordon980acb92014-05-31 10:31:19 -07002400 }
2401
Santos Cordona4868042014-09-04 17:39:22 -07002402 private void mergeConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002403 Log.i(this, "mergeConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002404 Conference conference = findConferenceForAction(callId, "mergeConference");
2405 if (conference != null) {
2406 conference.onMerge();
2407 }
2408 }
2409
2410 private void swapConference(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002411 Log.i(this, "swapConference(%s)", callId);
Santos Cordona4868042014-09-04 17:39:22 -07002412 Conference conference = findConferenceForAction(callId, "swapConference");
2413 if (conference != null) {
2414 conference.onSwap();
2415 }
2416 }
2417
Ravi Paluri404babb2020-01-23 19:02:44 +05302418 private void addConferenceParticipants(String callId, List<Uri> participants) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002419 Log.i(this, "addConferenceParticipants(%s)", callId);
Ravi Paluri404babb2020-01-23 19:02:44 +05302420 if (mConnectionById.containsKey(callId)) {
2421 findConnectionForAction(callId, "addConferenceParticipants")
2422 .onAddConferenceParticipants(participants);
2423 } else {
2424 findConferenceForAction(callId, "addConferenceParticipants")
2425 .onAddConferenceParticipants(participants);
2426 }
2427 }
2428
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002429 /**
2430 * Notifies a {@link Connection} of a request to pull an external call.
2431 *
2432 * See {@link Call#pullExternalCall()}.
2433 *
2434 * @param callId The ID of the call to pull.
2435 */
2436 private void pullExternalCall(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002437 Log.i(this, "pullExternalCall(%s)", callId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002438 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2439 if (connection != null) {
2440 connection.onPullExternalCall();
2441 }
2442 }
2443
2444 /**
2445 * Notifies a {@link Connection} of a call event.
2446 *
2447 * See {@link Call#sendCallEvent(String, Bundle)}.
2448 *
2449 * @param callId The ID of the call receiving the event.
2450 * @param event The event.
2451 * @param extras Extras associated with the event.
2452 */
2453 private void sendCallEvent(String callId, String event, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002454 Log.i(this, "sendCallEvent(%s, %s)", callId, event);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002455 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2456 if (connection != null) {
2457 connection.onCallEvent(event, extras);
2458 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002459 }
2460
Hall Liu73903142021-02-18 18:41:41 -08002461 private void onCallFilteringCompleted(String callId, Connection.CallFilteringCompletionInfo
2462 callFilteringCompletionInfo) {
2463 Log.i(this, "onCallFilteringCompleted(%s, %s)", callId, callFilteringCompletionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08002464 Connection connection = findConnectionForAction(callId, "onCallFilteringCompleted");
2465 if (connection != null) {
Hall Liu73903142021-02-18 18:41:41 -08002466 connection.onCallFilteringCompleted(callFilteringCompletionInfo);
Hall Liu49cabcc2021-01-15 11:41:48 -08002467 }
2468 }
2469
Tyler Gunndee56a82016-03-23 16:06:34 -07002470 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002471 * Notifies a {@link Connection} that a handover has completed.
2472 *
2473 * @param callId The ID of the call which completed handover.
2474 */
2475 private void notifyHandoverComplete(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002476 Log.i(this, "notifyHandoverComplete(%s)", callId);
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002477 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2478 if (connection != null) {
2479 connection.onHandoverComplete();
2480 }
2481 }
2482
2483 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002484 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2485 * <p>
2486 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2487 * the {@link android.telecom.Call#putExtra(String, boolean)},
2488 * {@link android.telecom.Call#putExtra(String, int)},
2489 * {@link android.telecom.Call#putExtra(String, String)},
2490 * {@link Call#removeExtras(List)}.
2491 *
2492 * @param callId The ID of the call receiving the event.
2493 * @param extras The new extras bundle.
2494 */
2495 private void handleExtrasChanged(String callId, Bundle extras) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002496 Log.i(this, "handleExtrasChanged(%s, %s)", callId, extras);
Tyler Gunndee56a82016-03-23 16:06:34 -07002497 if (mConnectionById.containsKey(callId)) {
2498 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2499 } else if (mConferenceById.containsKey(callId)) {
2500 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2501 }
2502 }
2503
Hall Liub64ac4c2017-02-06 10:49:48 -08002504 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002505 Log.i(this, "startRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002506 if (mConnectionById.containsKey(callId)) {
2507 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2508 } else if (mConferenceById.containsKey(callId)) {
2509 Log.w(this, "startRtt called on a conference.");
2510 }
2511 }
2512
2513 private void stopRtt(String callId) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002514 Log.i(this, "stopRtt(%s)", callId);
Hall Liub64ac4c2017-02-06 10:49:48 -08002515 if (mConnectionById.containsKey(callId)) {
2516 findConnectionForAction(callId, "stopRtt").onStopRtt();
2517 } else if (mConferenceById.containsKey(callId)) {
2518 Log.w(this, "stopRtt called on a conference.");
2519 }
2520 }
2521
2522 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002523 Log.i(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
Hall Liub64ac4c2017-02-06 10:49:48 -08002524 if (mConnectionById.containsKey(callId)) {
2525 findConnectionForAction(callId, "handleRttUpgradeResponse")
2526 .handleRttUpgradeResponse(rttTextStream);
2527 } else if (mConferenceById.containsKey(callId)) {
2528 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2529 }
2530 }
2531
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002532 private void onPostDialContinue(String callId, boolean proceed) {
Tyler Gunnffbcd892020-05-04 15:01:59 -07002533 Log.i(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002534 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002535 }
2536
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002537 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002538 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002539 // No need to query again if we already did it.
2540 return;
2541 }
2542
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002543 String callingPackage = getOpPackageName();
2544
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002545 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002546 @Override
2547 public void onResult(
2548 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002549 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002550 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002551 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002552 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002553 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002554 mRemoteConnectionManager.addConnectionService(
2555 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002556 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002557 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002558 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002559 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002560 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002561 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002562 }
2563
2564 @Override
2565 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002566 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002567 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002568 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002569 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002570 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002571 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002572 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002573 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002574 }
2575
Ihab Awadf8b69882014-07-25 15:14:01 -07002576 /**
2577 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002578 * incoming request. This is used by {@code ConnectionService}s that are registered with
2579 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2580 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002581 *
2582 * @param connectionManagerPhoneAccount See description at
2583 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2584 * @param request Details about the incoming call.
2585 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2586 * not handle the call.
2587 */
2588 public final RemoteConnection createRemoteIncomingConnection(
2589 PhoneAccountHandle connectionManagerPhoneAccount,
2590 ConnectionRequest request) {
2591 return mRemoteConnectionManager.createRemoteConnection(
2592 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002593 }
2594
2595 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002596 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002597 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2598 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2599 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002600 *
2601 * @param connectionManagerPhoneAccount See description at
2602 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002603 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002604 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2605 * not handle the call.
2606 */
2607 public final RemoteConnection createRemoteOutgoingConnection(
2608 PhoneAccountHandle connectionManagerPhoneAccount,
2609 ConnectionRequest request) {
2610 return mRemoteConnectionManager.createRemoteConnection(
2611 connectionManagerPhoneAccount, request, false);
2612 }
2613
2614 /**
Grace Jia9a09c672020-08-04 12:52:09 -07002615 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2616 * incoming request. This is used by {@code ConnectionService}s that are registered with
2617 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2618 *
2619 * @param connectionManagerPhoneAccount See description at
2620 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2621 * @param request Details about the incoming conference call.
2622 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2623 * handle the call.
2624 */
2625 public final @Nullable RemoteConference createRemoteIncomingConference(
2626 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2627 @Nullable ConnectionRequest request) {
2628 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2629 request, true);
2630 }
2631
2632 /**
2633 * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
2634 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2635 * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
2636 *
2637 * @param connectionManagerPhoneAccount See description at
2638 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2639 * @param request Details about the outgoing conference call.
2640 * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
2641 * handle the call.
2642 */
2643 public final @Nullable RemoteConference createRemoteOutgoingConference(
2644 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2645 @Nullable ConnectionRequest request) {
2646 return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
2647 request, false);
2648 }
2649
2650 /**
Santos Cordona663f862014-10-29 13:49:58 -07002651 * Indicates to the relevant {@code RemoteConnectionService} that the specified
2652 * {@link RemoteConnection}s should be merged into a conference call.
2653 * <p>
2654 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
2655 * be invoked.
2656 *
2657 * @param remoteConnection1 The first of the remote connections to conference.
2658 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07002659 */
2660 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07002661 RemoteConnection remoteConnection1,
2662 RemoteConnection remoteConnection2) {
2663 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07002664 }
2665
2666 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002667 * Adds a new conference call. When a conference call is created either as a result of an
2668 * explicit request via {@link #onConference} or otherwise, the connection service should supply
2669 * an instance of {@link Conference} by invoking this method. A conference call provided by this
2670 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
2671 *
2672 * @param conference The new conference object.
2673 */
2674 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07002675 Log.d(this, "addConference: conference=%s", conference);
2676
Santos Cordon823fd3c2014-08-07 18:35:18 -07002677 String id = addConferenceInternal(conference);
2678 if (id != null) {
2679 List<String> connectionIds = new ArrayList<>(2);
2680 for (Connection connection : conference.getConnections()) {
2681 if (mIdByConnection.containsKey(connection)) {
2682 connectionIds.add(mIdByConnection.get(connection));
2683 }
2684 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002685 conference.setTelecomCallId(id);
Brad Ebinger0ae44ed2020-04-09 15:30:57 -07002686 ParcelableConference parcelableConference = new ParcelableConference.Builder(
2687 conference.getPhoneAccountHandle(), conference.getState())
2688 .setConnectionCapabilities(conference.getConnectionCapabilities())
2689 .setConnectionProperties(conference.getConnectionProperties())
2690 .setConnectionIds(connectionIds)
2691 .setVideoAttributes(conference.getVideoProvider() == null
2692 ? null : conference.getVideoProvider().getInterface(),
2693 conference.getVideoState())
2694 .setConnectTimeMillis(conference.getConnectTimeMillis(),
2695 conference.getConnectionStartElapsedRealtimeMillis())
2696 .setStatusHints(conference.getStatusHints())
2697 .setExtras(conference.getExtras())
2698 .setAddress(conference.getAddress(), conference.getAddressPresentation())
2699 .setCallerDisplayName(conference.getCallerDisplayName(),
2700 conference.getCallerDisplayNamePresentation())
2701 .setDisconnectCause(conference.getDisconnectCause())
2702 .setRingbackRequested(conference.isRingbackRequested())
2703 .setCallDirection(conference.getCallDirection())
2704 .build();
Andrew Lee0f51da32015-04-16 13:11:55 -07002705
Santos Cordon823fd3c2014-08-07 18:35:18 -07002706 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07002707 mAdapter.setVideoProvider(id, conference.getVideoProvider());
2708 mAdapter.setVideoState(id, conference.getVideoState());
Tyler Gunn10362372020-04-08 13:12:30 -07002709 // In some instances a conference can start its life as a standalone call with just a
2710 // single participant; ensure we signal to Telecom in this case.
2711 if (!conference.isMultiparty()) {
2712 mAdapter.setConferenceState(id, conference.isMultiparty());
2713 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002714
2715 // Go through any child calls and set the parent.
2716 for (Connection connection : conference.getConnections()) {
2717 String connectionId = mIdByConnection.get(connection);
2718 if (connectionId != null) {
2719 mAdapter.setIsConferenced(connectionId, id);
2720 }
2721 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002722 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002723 }
2724 }
2725
2726 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002727 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
2728 * connection.
2729 *
2730 * @param phoneAccountHandle The phone account handle for the connection.
2731 * @param connection The connection to add.
2732 */
2733 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
2734 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07002735 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
2736 }
2737
2738 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002739 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
2740 * microphone, camera).
2741 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08002742 * <p>
2743 * The {@link ConnectionService} will be disconnected when it failed to call this method within
2744 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
2745 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08002746 * @see ConnectionService#onConnectionServiceFocusLost()
2747 */
2748 public final void connectionServiceFocusReleased() {
2749 mAdapter.onConnectionServiceFocusReleased();
2750 }
2751
2752 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07002753 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07002754 * connection, as well as adding that connection to the specified conference.
2755 * <p>
2756 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
2757 * IMS conference participants to be added to a conference in a single step; this helps ensure
2758 * UI updates happen atomically, rather than adding the connection and then adding it to
2759 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07002760 *
2761 * @param phoneAccountHandle The phone account handle for the connection.
2762 * @param connection The connection to add.
2763 * @param conference The parent conference of the new connection.
2764 * @hide
2765 */
Tyler Gunn5567d742019-10-31 13:04:37 -07002766 @SystemApi
2767 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
2768 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002769
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002770 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002771 if (id != null) {
2772 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07002773 String conferenceId = null;
2774 if (conference != null) {
2775 conferenceId = mIdByConference.get(conference);
2776 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002777
2778 ParcelableConnection parcelableConnection = new ParcelableConnection(
2779 phoneAccountHandle,
2780 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002781 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002782 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002783 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002784 connection.getAddress(),
2785 connection.getAddressPresentation(),
2786 connection.getCallerDisplayName(),
2787 connection.getCallerDisplayNamePresentation(),
2788 connection.getVideoProvider() == null ?
2789 null : connection.getVideoProvider().getInterface(),
2790 connection.getVideoState(),
2791 connection.isRingbackRequested(),
2792 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002793 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002794 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002795 connection.getStatusHints(),
2796 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002797 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07002798 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07002799 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002800 connection.getCallDirection(),
2801 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002802 mAdapter.addExistingConnection(id, parcelableConnection);
2803 }
2804 }
2805
2806 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002807 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
2808 * has taken responsibility.
2809 *
2810 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07002811 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07002812 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07002813 return mConnectionById.values();
2814 }
2815
2816 /**
Santos Cordona6018b92016-02-16 14:23:12 -08002817 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
2818 * has taken responsibility.
2819 *
2820 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
2821 */
2822 public final Collection<Conference> getAllConferences() {
2823 return mConferenceById.values();
2824 }
2825
2826 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002827 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2828 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07002829 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002830 * @param connectionManagerPhoneAccount See description at
2831 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2832 * @param request Details about the incoming call.
2833 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2834 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002835 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002836 public Connection onCreateIncomingConnection(
2837 PhoneAccountHandle connectionManagerPhoneAccount,
2838 ConnectionRequest request) {
2839 return null;
2840 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302841 /**
Grace Jia8587ee52020-07-10 15:42:32 -07002842 * Create a {@code Conference} given an incoming request. This is used to attach to an incoming
2843 * conference call initiated via
2844 * {@link TelecomManager#addNewIncomingConference(PhoneAccountHandle, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05302845 *
2846 * @param connectionManagerPhoneAccount See description at
2847 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Grace Jia8587ee52020-07-10 15:42:32 -07002848 * @param request Details about the incoming conference call.
2849 * @return The {@code Conference} object to satisfy this call, or {@code null} to
Ravi Paluri80aa2142019-12-02 11:57:37 +05302850 * not handle the call.
2851 */
2852 public @Nullable Conference onCreateIncomingConference(
2853 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2854 @Nullable ConnectionRequest request) {
2855 return null;
2856 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002857
2858 /**
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002859 * Called after the {@link Connection} returned by
2860 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
2861 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
2862 * added to the {@link ConnectionService} and sent to Telecom.
2863 *
2864 * @param connection the {@link Connection}.
2865 * @hide
2866 */
2867 public void onCreateConnectionComplete(Connection connection) {
2868 }
2869
2870 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302871 * Called after the {@link Conference} returned by
2872 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
2873 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
2874 * added to the {@link ConnectionService} and sent to Telecom.
2875 *
2876 * @param conference the {@link Conference}.
2877 * @hide
2878 */
2879 public void onCreateConferenceComplete(Conference conference) {
2880 }
2881
2882
2883 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002884 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2885 * incoming {@link Connection} was denied.
2886 * <p>
2887 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2888 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
2889 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2890 * {@link Connection}.
2891 * <p>
2892 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2893 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002894 * @param connectionManagerPhoneAccount See description at
2895 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002896 * @param request The incoming connection request.
2897 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002898 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2899 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002900 }
2901
2902 /**
2903 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2904 * outgoing {@link Connection} was denied.
2905 * <p>
2906 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2907 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
2908 * The {@link ConnectionService} is responisible for informing the user that the
2909 * {@link Connection} cannot be made at this time.
2910 * <p>
2911 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2912 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002913 * @param connectionManagerPhoneAccount See description at
2914 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002915 * @param request The outgoing connection request.
2916 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002917 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2918 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002919 }
2920
2921 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302922 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2923 * incoming {@link Conference} was denied.
2924 * <p>
2925 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2926 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
2927 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2928 * {@link Conference}.
2929 * <p>
2930 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2931 *
2932 * @param connectionManagerPhoneAccount See description at
2933 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2934 * @param request The incoming connection request.
2935 */
2936 public void onCreateIncomingConferenceFailed(
2937 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2938 @Nullable ConnectionRequest request) {
2939 }
2940
2941 /**
2942 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2943 * outgoing {@link Conference} was denied.
2944 * <p>
2945 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2946 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
2947 * The {@link ConnectionService} is responisible for informing the user that the
2948 * {@link Conference} cannot be made at this time.
2949 * <p>
2950 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2951 *
2952 * @param connectionManagerPhoneAccount See description at
2953 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2954 * @param request The outgoing connection request.
2955 */
2956 public void onCreateOutgoingConferenceFailed(
2957 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2958 @Nullable ConnectionRequest request) {
2959 }
2960
2961
2962 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002963 * Trigger recalculate functinality for conference calls. This is used when a Telephony
2964 * Connection is part of a conference controller but is not yet added to Connection
2965 * Service and hence cannot be added to the conference call.
2966 *
2967 * @hide
2968 */
2969 public void triggerConferenceRecalculate() {
2970 }
2971
2972 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002973 * Create a {@code Connection} given an outgoing request. This is used to initiate new
2974 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002975 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002976 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2977 * this call.
2978 * <p>
2979 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2980 * has registered one or more {@code PhoneAccount}s having
2981 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2982 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2983 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2984 * making the connection.
2985 * <p>
2986 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2987 * being asked to make a direct connection. The
2988 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2989 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2990 * making the connection.
2991 * @param request Details about the outgoing call.
2992 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002993 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002994 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002995 public Connection onCreateOutgoingConnection(
2996 PhoneAccountHandle connectionManagerPhoneAccount,
2997 ConnectionRequest request) {
2998 return null;
2999 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003000
3001 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05303002 * Create a {@code Conference} given an outgoing request. This is used to initiate new
Grace Jia8587ee52020-07-10 15:42:32 -07003003 * outgoing conference call requested via
3004 * {@link TelecomManager#startConference(List, Bundle)}.
Ravi Paluri80aa2142019-12-02 11:57:37 +05303005 *
3006 * @param connectionManagerPhoneAccount The connection manager account to use for managing
3007 * this call.
3008 * <p>
3009 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
3010 * has registered one or more {@code PhoneAccount}s having
3011 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
3012 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
3013 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
3014 * making the connection.
3015 * <p>
3016 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
3017 * being asked to make a direct connection. The
3018 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
3019 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
3020 * making the connection.
3021 * @param request Details about the outgoing call.
3022 * @return The {@code Conference} object to satisfy this call, or the result of an invocation
3023 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
3024 */
3025 public @Nullable Conference onCreateOutgoingConference(
3026 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
3027 @Nullable ConnectionRequest request) {
3028 return null;
3029 }
3030
3031
3032 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003033 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3034 * outgoing handover {@link Connection}.
3035 * <p>
3036 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3037 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3038 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3039 * is referred to as the source of the handover, and the video calling app is referred to as the
3040 * destination.
3041 * <p>
3042 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3043 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3044 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3045 * device.
3046 * <p>
3047 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
3048 * device when the user initiates a handover request from one app to another. The user request
3049 * originates in the {@link InCallService} via
3050 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3051 * <p>
3052 * For a full discussion of the handover process and the APIs involved, see
3053 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3054 * <p>
3055 * Implementations of this method should return an instance of {@link Connection} which
3056 * represents the handover. If your app does not wish to accept a handover to it at this time,
3057 * you can return {@code null}. The code below shows an example of how this is done.
3058 * <pre>
3059 * {@code
3060 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3061 * fromPhoneAccountHandle, ConnectionRequest request) {
3062 * if (!isHandoverAvailable()) {
3063 * return null;
3064 * }
3065 * MyConnection connection = new MyConnection();
3066 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3067 * connection.setVideoState(request.getVideoState());
3068 * return connection;
3069 * }
3070 * }
3071 * </pre>
3072 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003073 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3074 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08003075 * @param request Details about the call to handover.
3076 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003077 */
3078 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3079 ConnectionRequest request) {
3080 return null;
3081 }
3082
3083 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08003084 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
3085 * incoming handover {@link Connection}.
3086 * <p>
3087 * A call handover is the process where an ongoing call is transferred from one app (i.e.
3088 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
3089 * mobile network call in a video calling app. The mobile network call via the Telephony stack
3090 * is referred to as the source of the handover, and the video calling app is referred to as the
3091 * destination.
3092 * <p>
3093 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
3094 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
3095 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
3096 * device.
3097 * <p>
3098 * This method is called on the destination app on the <em>receiving</em> device when the
3099 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
3100 * accept an incoming handover from the <em>initiating</em> device.
3101 * <p>
3102 * For a full discussion of the handover process and the APIs involved, see
3103 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
3104 * <p>
3105 * Implementations of this method should return an instance of {@link Connection} which
3106 * represents the handover. The code below shows an example of how this is done.
3107 * <pre>
3108 * {@code
3109 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
3110 * fromPhoneAccountHandle, ConnectionRequest request) {
3111 * // Given that your app requested to accept the handover, you should not return null here.
3112 * MyConnection connection = new MyConnection();
3113 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
3114 * connection.setVideoState(request.getVideoState());
3115 * return connection;
3116 * }
3117 * }
3118 * </pre>
3119 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07003120 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
3121 * ConnectionService which needs to handover the call.
3122 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08003123 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07003124 */
3125 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
3126 ConnectionRequest request) {
3127 return null;
3128 }
3129
3130 /**
3131 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
3132 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08003133 * <p>
3134 * For a full discussion of the handover process and the APIs involved, see
3135 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
3136 *
3137 * @param request Details about the call which failed to handover.
3138 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07003139 */
Tyler Gunn9d127732018-03-02 15:45:51 -08003140 public void onHandoverFailed(ConnectionRequest request,
3141 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07003142 return;
3143 }
3144
3145 /**
Yorke Leec3cf9822014-10-02 09:38:39 -07003146 * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
3147 * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
3148 * call created using
3149 * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
3150 *
Yorke Lee770ed6e2014-10-06 18:58:52 -07003151 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07003152 */
3153 public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
3154 ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003155 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07003156 }
3157
3158 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003159 * Conference two specified connections. Invoked when the user has made a request to merge the
3160 * specified connections into a conference call. In response, the connection service should
3161 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07003162 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07003163 * @param connection1 A connection to merge into a conference call.
3164 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07003165 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07003166 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07003167
Santos Cordona663f862014-10-29 13:49:58 -07003168 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07003169 * Called when a connection is added.
3170 * @hide
3171 */
3172 public void onConnectionAdded(Connection connection) {}
3173
3174 /**
3175 * Called when a connection is removed.
3176 * @hide
3177 */
3178 public void onConnectionRemoved(Connection connection) {}
3179
3180 /**
3181 * Called when a conference is added.
3182 * @hide
3183 */
3184 public void onConferenceAdded(Conference conference) {}
3185
3186 /**
3187 * Called when a conference is removed.
3188 * @hide
3189 */
3190 public void onConferenceRemoved(Conference conference) {}
3191
3192 /**
Santos Cordona663f862014-10-29 13:49:58 -07003193 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
3194 * When this method is invoked, this {@link ConnectionService} should create its own
3195 * representation of the conference call and send it to telecom using {@link #addConference}.
3196 * <p>
3197 * This is only relevant to {@link ConnectionService}s which are registered with
3198 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
3199 *
3200 * @param conference The remote conference call.
3201 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07003202 public void onRemoteConferenceAdded(RemoteConference conference) {}
3203
Santos Cordon823fd3c2014-08-07 18:35:18 -07003204 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003205 * Called when an existing connection is added remotely.
3206 * @param connection The existing connection which was added.
3207 */
3208 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
3209
3210 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08003211 * Called when the {@link ConnectionService} has lost the call focus.
3212 * The {@link ConnectionService} should release the call resources and invokes
3213 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
3214 * released the call resources.
3215 */
3216 public void onConnectionServiceFocusLost() {}
3217
3218 /**
3219 * Called when the {@link ConnectionService} has gained the call focus. The
3220 * {@link ConnectionService} can acquire the call resources at this time.
3221 */
3222 public void onConnectionServiceFocusGained() {}
3223
3224 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07003225 * @hide
3226 */
3227 public boolean containsConference(Conference conference) {
3228 return mIdByConference.containsKey(conference);
3229 }
3230
Ihab Awadb8e85c72014-08-23 20:34:57 -07003231 /** {@hide} */
3232 void addRemoteConference(RemoteConference remoteConference) {
3233 onRemoteConferenceAdded(remoteConference);
3234 }
3235
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003236 /** {@hide} */
3237 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
3238 onRemoteExistingConnectionAdded(remoteConnection);
3239 }
3240
Ihab Awad5d0410f2014-07-30 10:07:40 -07003241 private void onAccountsInitialized() {
3242 mAreAccountsInitialized = true;
3243 for (Runnable r : mPreInitializationConnectionRequests) {
3244 r.run();
3245 }
3246 mPreInitializationConnectionRequests.clear();
3247 }
3248
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003249 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003250 * Adds an existing connection to the list of connections, identified by a new call ID unique
3251 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003252 *
3253 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003254 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003255 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003256 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
3257 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003258
3259 if (connection.getExtras() != null && connection.getExtras()
3260 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3261 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3262 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
3263 connection.getTelecomCallId(), id);
3264 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003265 // If no phone account handle was provided, we cannot be sure the call ID is unique,
3266 // so just use a random UUID.
3267 id = UUID.randomUUID().toString();
3268 } else {
3269 // Phone account handle was provided, so use the ConnectionService class name as a
3270 // prefix for a unique incremental call ID.
3271 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
3272 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07003273 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07003274 return id;
3275 }
3276
Pengquan Meng70c9885332017-10-02 18:09:03 -07003277 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003278 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003279 mConnectionById.put(callId, connection);
3280 mIdByConnection.put(connection, callId);
3281 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003282 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003283 connection.setPhoneAccountHandle(handle);
3284 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003285 }
3286
Anthony Lee30e65842014-11-06 16:30:53 -08003287 /** {@hide} */
3288 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003289 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003290 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003291 String id = mIdByConnection.get(connection);
3292 if (id != null) {
3293 mConnectionById.remove(id);
3294 mIdByConnection.remove(connection);
3295 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003296 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003297 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003298 }
3299
Santos Cordon823fd3c2014-08-07 18:35:18 -07003300 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003301 String originalId = null;
3302 if (conference.getExtras() != null && conference.getExtras()
3303 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3304 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3305 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3306 conference.getTelecomCallId(),
3307 originalId);
3308 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003309 if (mIdByConference.containsKey(conference)) {
3310 Log.w(this, "Re-adding an existing conference: %s.", conference);
3311 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003312 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3313 // cannot determine a ConnectionService class name to associate with the ID, so use
3314 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003315 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003316 mConferenceById.put(id, conference);
3317 mIdByConference.put(conference, id);
3318 conference.addListener(mConferenceListener);
3319 return id;
3320 }
3321
3322 return null;
3323 }
3324
3325 private void removeConference(Conference conference) {
3326 if (mIdByConference.containsKey(conference)) {
3327 conference.removeListener(mConferenceListener);
3328
3329 String id = mIdByConference.get(conference);
3330 mConferenceById.remove(id);
3331 mIdByConference.remove(conference);
3332 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003333
3334 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003335 }
3336 }
3337
Ihab Awad542e0ea2014-05-16 10:22:16 -07003338 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003339 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003340 return mConnectionById.get(callId);
3341 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003342 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003343 return getNullConnection();
3344 }
3345
3346 static synchronized Connection getNullConnection() {
3347 if (sNullConnection == null) {
3348 sNullConnection = new Connection() {};
3349 }
3350 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003351 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003352
3353 private Conference findConferenceForAction(String conferenceId, String action) {
3354 if (mConferenceById.containsKey(conferenceId)) {
3355 return mConferenceById.get(conferenceId);
3356 }
3357 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3358 return getNullConference();
3359 }
3360
Ihab Awadb8e85c72014-08-23 20:34:57 -07003361 private List<String> createConnectionIdList(List<Connection> connections) {
3362 List<String> ids = new ArrayList<>();
3363 for (Connection c : connections) {
3364 if (mIdByConnection.containsKey(c)) {
3365 ids.add(mIdByConnection.get(c));
3366 }
3367 }
3368 Collections.sort(ids);
3369 return ids;
3370 }
3371
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003372 /**
3373 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003374 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003375 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003376 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003377 * @return List of string conference and call Ids.
3378 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003379 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003380 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003381 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003382 // Only allow Connection and Conference conferenceables.
3383 if (c instanceof Connection) {
3384 Connection connection = (Connection) c;
3385 if (mIdByConnection.containsKey(connection)) {
3386 ids.add(mIdByConnection.get(connection));
3387 }
3388 } else if (c instanceof Conference) {
3389 Conference conference = (Conference) c;
3390 if (mIdByConference.containsKey(conference)) {
3391 ids.add(mIdByConference.get(conference));
3392 }
3393 }
3394 }
3395 Collections.sort(ids);
3396 return ids;
3397 }
3398
Santos Cordon0159ac02014-08-21 14:28:11 -07003399 private Conference getNullConference() {
3400 if (sNullConference == null) {
3401 sNullConference = new Conference(null) {};
3402 }
3403 return sNullConference;
3404 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003405
3406 private void endAllConnections() {
3407 // Unbound from telecomm. We should end all connections and conferences.
3408 for (Connection connection : mIdByConnection.keySet()) {
3409 // only operate on top-level calls. Conference calls will be removed on their own.
3410 if (connection.getConference() == null) {
3411 connection.onDisconnect();
3412 }
3413 }
3414 for (Conference conference : mIdByConference.keySet()) {
3415 conference.onDisconnect();
3416 }
3417 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003418
3419 /**
3420 * Retrieves the next call ID as maintainted by the connection service.
3421 *
3422 * @return The call ID.
3423 */
3424 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003425 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003426 return ++mId;
3427 }
3428 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003429
3430 /**
3431 * Returns this handler, ONLY FOR TESTING.
3432 * @hide
3433 */
3434 @VisibleForTesting
3435 public Handler getHandler() {
3436 return mHandler;
3437 }
Santos Cordon980acb92014-05-31 10:31:19 -07003438}