blob: 2aea723cf418ce6782e8a18e1618cf953935f68d [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";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700131 private static final String SESSION_REJECT = "CS.r";
132 private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
133 private static final String SESSION_SILENCE = "CS.s";
134 private static final String SESSION_DISCONNECT = "CS.d";
135 private static final String SESSION_HOLD = "CS.h";
136 private static final String SESSION_UNHOLD = "CS.u";
137 private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
138 private static final String SESSION_PLAY_DTMF = "CS.pDT";
139 private static final String SESSION_STOP_DTMF = "CS.sDT";
140 private static final String SESSION_CONFERENCE = "CS.c";
141 private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
142 private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
143 private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
Ravi Paluri404babb2020-01-23 19:02:44 +0530144 private static final String SESSION_ADD_PARTICIPANT = "CS.aP";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700145 private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
146 private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
147 private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800148 private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700149 private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
Hall Liub64ac4c2017-02-06 10:49:48 -0800150 private static final String SESSION_START_RTT = "CS.+RTT";
Hall Liua549fed2018-02-09 16:40:03 -0800151 private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
Hall Liub64ac4c2017-02-06 10:49:48 -0800152 private static final String SESSION_STOP_RTT = "CS.-RTT";
153 private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
Pengquan Meng731c1a32017-11-21 18:01:13 -0800154 private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
155 private static final String SESSION_CONNECTION_SERVICE_FOCUS_GAINED = "CS.cSFG";
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800156 private static final String SESSION_HANDOVER_FAILED = "CS.haF";
Ravi Paluri80aa2142019-12-02 11:57:37 +0530157 private static final String SESSION_CREATE_CONF = "CS.crConf";
158 private static final String SESSION_CREATE_CONF_COMPLETE = "CS.crConfC";
159 private static final String SESSION_CREATE_CONF_FAILED = "CS.crConfF";
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700160
Ihab Awad8aecfed2014-08-08 17:06:11 -0700161 private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700162 private static final int MSG_CREATE_CONNECTION = 2;
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700163 private static final int MSG_ABORT = 3;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700164 private static final int MSG_ANSWER = 4;
165 private static final int MSG_REJECT = 5;
166 private static final int MSG_DISCONNECT = 6;
167 private static final int MSG_HOLD = 7;
168 private static final int MSG_UNHOLD = 8;
Yorke Lee4af59352015-05-13 14:14:54 -0700169 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
Sailesh Nepalc5b01572014-07-14 16:29:44 -0700170 private static final int MSG_PLAY_DTMF_TONE = 10;
171 private static final int MSG_STOP_DTMF_TONE = 11;
172 private static final int MSG_CONFERENCE = 12;
173 private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700174 private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700175 private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
Tyler Gunnbe74de02014-08-29 14:51:48 -0700176 private static final int MSG_ANSWER_VIDEO = 17;
Santos Cordona4868042014-09-04 17:39:22 -0700177 private static final int MSG_MERGE_CONFERENCE = 18;
178 private static final int MSG_SWAP_CONFERENCE = 19;
Bryce Lee81901682015-08-28 16:38:02 -0700179 private static final int MSG_REJECT_WITH_MESSAGE = 20;
Bryce Leecac50772015-11-17 15:13:29 -0800180 private static final int MSG_SILENCE = 21;
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700181 private static final int MSG_PULL_EXTERNAL_CALL = 22;
182 private static final int MSG_SEND_CALL_EVENT = 23;
Tyler Gunndee56a82016-03-23 16:06:34 -0700183 private static final int MSG_ON_EXTRAS_CHANGED = 24;
Tyler Gunn44e01912017-01-31 10:49:05 -0800184 private static final int MSG_CREATE_CONNECTION_FAILED = 25;
Hall Liub64ac4c2017-02-06 10:49:48 -0800185 private static final int MSG_ON_START_RTT = 26;
186 private static final int MSG_ON_STOP_RTT = 27;
187 private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700188 private static final int MSG_CREATE_CONNECTION_COMPLETE = 29;
Pengquan Meng731c1a32017-11-21 18:01:13 -0800189 private static final int MSG_CONNECTION_SERVICE_FOCUS_LOST = 30;
190 private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800191 private static final int MSG_HANDOVER_FAILED = 32;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800192 private static final int MSG_HANDOVER_COMPLETE = 33;
Pooja Jaind34698d2017-12-28 14:15:31 +0530193 private static final int MSG_DEFLECT = 34;
Ravi Paluri80aa2142019-12-02 11:57:37 +0530194 private static final int MSG_CREATE_CONFERENCE = 35;
195 private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
196 private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800197 private static final int MSG_REJECT_WITH_REASON = 38;
Ravi Paluri404babb2020-01-23 19:02:44 +0530198 private static final int MSG_ADD_PARTICIPANT = 39;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -0700199
Sailesh Nepalcf7020b2014-08-20 10:07:19 -0700200 private static Connection sNullConnection;
201
mike dooley95e80702014-09-18 14:07:52 -0700202 private final Map<String, Connection> mConnectionById = new ConcurrentHashMap<>();
203 private final Map<Connection, String> mIdByConnection = new ConcurrentHashMap<>();
204 private final Map<String, Conference> mConferenceById = new ConcurrentHashMap<>();
205 private final Map<Conference, String> mIdByConference = new ConcurrentHashMap<>();
Ihab Awadb8e85c72014-08-23 20:34:57 -0700206 private final RemoteConnectionManager mRemoteConnectionManager =
207 new RemoteConnectionManager(this);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700208 private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>();
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700209 private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
Ihab Awad542e0ea2014-05-16 10:22:16 -0700210
Santos Cordon823fd3c2014-08-07 18:35:18 -0700211 private boolean mAreAccountsInitialized = false;
Santos Cordon0159ac02014-08-21 14:28:11 -0700212 private Conference sNullConference;
Tyler Gunnf0500bd2015-09-01 10:59:48 -0700213 private Object mIdSyncRoot = new Object();
214 private int mId = 0;
Santos Cordon823fd3c2014-08-07 18:35:18 -0700215
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700216 private final IBinder mBinder = new IConnectionService.Stub() {
217 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700218 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
219 Session.Info sessionInfo) {
220 Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
221 try {
222 SomeArgs args = SomeArgs.obtain();
223 args.arg1 = adapter;
224 args.arg2 = Log.createSubsession();
225 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
226 } finally {
227 Log.endSession();
228 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700229 }
230
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700231 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
232 Session.Info sessionInfo) {
233 Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
234 try {
235 SomeArgs args = SomeArgs.obtain();
236 args.arg1 = adapter;
237 args.arg2 = Log.createSubsession();
238 mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
239 } finally {
240 Log.endSession();
241 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700242 }
243
244 @Override
Ihab Awadf8b69882014-07-25 15:14:01 -0700245 public void createConnection(
246 PhoneAccountHandle connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700247 String id,
Ihab Awadf8b69882014-07-25 15:14:01 -0700248 ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700249 boolean isIncoming,
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700250 boolean isUnknown,
251 Session.Info sessionInfo) {
252 Log.startSession(sessionInfo, SESSION_CREATE_CONN);
253 try {
254 SomeArgs args = SomeArgs.obtain();
255 args.arg1 = connectionManagerPhoneAccount;
256 args.arg2 = id;
257 args.arg3 = request;
258 args.arg4 = Log.createSubsession();
259 args.argi1 = isIncoming ? 1 : 0;
260 args.argi2 = isUnknown ? 1 : 0;
261 mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
262 } finally {
263 Log.endSession();
264 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700265 }
266
267 @Override
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700268 public void createConnectionComplete(String id, Session.Info sessionInfo) {
269 Log.startSession(sessionInfo, SESSION_CREATE_CONN_COMPLETE);
270 try {
271 SomeArgs args = SomeArgs.obtain();
272 args.arg1 = id;
273 args.arg2 = Log.createSubsession();
274 mHandler.obtainMessage(MSG_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
275 } finally {
276 Log.endSession();
277 }
278 }
279
280 @Override
Tyler Gunn44e01912017-01-31 10:49:05 -0800281 public void createConnectionFailed(
Tyler Gunn159f35c2017-03-02 09:28:37 -0800282 PhoneAccountHandle connectionManagerPhoneAccount,
Tyler Gunn44e01912017-01-31 10:49:05 -0800283 String callId,
284 ConnectionRequest request,
285 boolean isIncoming,
286 Session.Info sessionInfo) {
287 Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
288 try {
289 SomeArgs args = SomeArgs.obtain();
290 args.arg1 = callId;
291 args.arg2 = request;
292 args.arg3 = Log.createSubsession();
Tyler Gunn159f35c2017-03-02 09:28:37 -0800293 args.arg4 = connectionManagerPhoneAccount;
Tyler Gunn44e01912017-01-31 10:49:05 -0800294 args.argi1 = isIncoming ? 1 : 0;
295 mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
296 } finally {
297 Log.endSession();
298 }
299 }
300
301 @Override
Ravi Paluri80aa2142019-12-02 11:57:37 +0530302 public void createConference(
303 PhoneAccountHandle connectionManagerPhoneAccount,
304 String id,
305 ConnectionRequest request,
306 boolean isIncoming,
307 boolean isUnknown,
308 Session.Info sessionInfo) {
309 Log.startSession(sessionInfo, SESSION_CREATE_CONF);
310 try {
311 SomeArgs args = SomeArgs.obtain();
312 args.arg1 = connectionManagerPhoneAccount;
313 args.arg2 = id;
314 args.arg3 = request;
315 args.arg4 = Log.createSubsession();
316 args.argi1 = isIncoming ? 1 : 0;
317 args.argi2 = isUnknown ? 1 : 0;
318 mHandler.obtainMessage(MSG_CREATE_CONFERENCE, args).sendToTarget();
319 } finally {
320 Log.endSession();
321 }
322 }
323
324 @Override
325 public void createConferenceComplete(String id, Session.Info sessionInfo) {
326 Log.startSession(sessionInfo, SESSION_CREATE_CONF_COMPLETE);
327 try {
328 SomeArgs args = SomeArgs.obtain();
329 args.arg1 = id;
330 args.arg2 = Log.createSubsession();
331 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_COMPLETE, args).sendToTarget();
332 } finally {
333 Log.endSession();
334 }
335 }
336
337 @Override
338 public void createConferenceFailed(
339 PhoneAccountHandle connectionManagerPhoneAccount,
340 String callId,
341 ConnectionRequest request,
342 boolean isIncoming,
343 Session.Info sessionInfo) {
344 Log.startSession(sessionInfo, SESSION_CREATE_CONF_FAILED);
345 try {
346 SomeArgs args = SomeArgs.obtain();
347 args.arg1 = callId;
348 args.arg2 = request;
349 args.arg3 = Log.createSubsession();
350 args.arg4 = connectionManagerPhoneAccount;
351 args.argi1 = isIncoming ? 1 : 0;
352 mHandler.obtainMessage(MSG_CREATE_CONFERENCE_FAILED, args).sendToTarget();
353 } finally {
354 Log.endSession();
355 }
356 }
357
358 @Override
Sanket Padawe4cc8ed52017-12-04 16:22:20 -0800359 public void handoverFailed(String callId, ConnectionRequest request, int reason,
360 Session.Info sessionInfo) {
361 Log.startSession(sessionInfo, SESSION_HANDOVER_FAILED);
362 try {
363 SomeArgs args = SomeArgs.obtain();
364 args.arg1 = callId;
365 args.arg2 = request;
366 args.arg3 = Log.createSubsession();
367 args.arg4 = reason;
368 mHandler.obtainMessage(MSG_HANDOVER_FAILED, args).sendToTarget();
369 } finally {
370 Log.endSession();
371 }
372 }
373
374 @Override
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800375 public void handoverComplete(String callId, Session.Info sessionInfo) {
376 Log.startSession(sessionInfo, SESSION_HANDOVER_COMPLETE);
377 try {
378 SomeArgs args = SomeArgs.obtain();
379 args.arg1 = callId;
380 args.arg2 = Log.createSubsession();
381 mHandler.obtainMessage(MSG_HANDOVER_COMPLETE, args).sendToTarget();
382 } finally {
383 Log.endSession();
384 }
385 }
386
387 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700388 public void abort(String callId, Session.Info sessionInfo) {
389 Log.startSession(sessionInfo, SESSION_ABORT);
390 try {
391 SomeArgs args = SomeArgs.obtain();
392 args.arg1 = callId;
393 args.arg2 = Log.createSubsession();
394 mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
395 } finally {
396 Log.endSession();
397 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700398 }
399
400 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700401 public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
402 Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
403 try {
404 SomeArgs args = SomeArgs.obtain();
405 args.arg1 = callId;
406 args.arg2 = Log.createSubsession();
407 args.argi1 = videoState;
408 mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
409 } finally {
410 Log.endSession();
411 }
Tyler Gunnbe74de02014-08-29 14:51:48 -0700412 }
413
414 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700415 public void answer(String callId, Session.Info sessionInfo) {
416 Log.startSession(sessionInfo, SESSION_ANSWER);
417 try {
418 SomeArgs args = SomeArgs.obtain();
419 args.arg1 = callId;
420 args.arg2 = Log.createSubsession();
421 mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
422 } finally {
423 Log.endSession();
424 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700425 }
426
427 @Override
Pooja Jaind34698d2017-12-28 14:15:31 +0530428 public void deflect(String callId, Uri address, Session.Info sessionInfo) {
429 Log.startSession(sessionInfo, SESSION_DEFLECT);
430 try {
431 SomeArgs args = SomeArgs.obtain();
432 args.arg1 = callId;
433 args.arg2 = address;
434 args.arg3 = Log.createSubsession();
435 mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
436 } finally {
437 Log.endSession();
438 }
439 }
440
441 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700442 public void reject(String callId, Session.Info sessionInfo) {
443 Log.startSession(sessionInfo, SESSION_REJECT);
444 try {
445 SomeArgs args = SomeArgs.obtain();
446 args.arg1 = callId;
447 args.arg2 = Log.createSubsession();
448 mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
449 } finally {
450 Log.endSession();
451 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700452 }
453
454 @Override
Tyler Gunnfacfdee2020-01-23 13:10:37 -0800455 public void rejectWithReason(String callId,
456 @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
457 Log.startSession(sessionInfo, SESSION_REJECT);
458 try {
459 SomeArgs args = SomeArgs.obtain();
460 args.arg1 = callId;
461 args.argi1 = rejectReason;
462 args.arg2 = Log.createSubsession();
463 mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
464 } finally {
465 Log.endSession();
466 }
467 }
468
469 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700470 public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
471 Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
472 try {
473 SomeArgs args = SomeArgs.obtain();
474 args.arg1 = callId;
475 args.arg2 = message;
476 args.arg3 = Log.createSubsession();
477 mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
478 } finally {
479 Log.endSession();
480 }
Bryce Lee81901682015-08-28 16:38:02 -0700481 }
482
483 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700484 public void silence(String callId, Session.Info sessionInfo) {
485 Log.startSession(sessionInfo, SESSION_SILENCE);
486 try {
487 SomeArgs args = SomeArgs.obtain();
488 args.arg1 = callId;
489 args.arg2 = Log.createSubsession();
490 mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
491 } finally {
492 Log.endSession();
493 }
Bryce Leecac50772015-11-17 15:13:29 -0800494 }
495
496 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700497 public void disconnect(String callId, Session.Info sessionInfo) {
498 Log.startSession(sessionInfo, SESSION_DISCONNECT);
499 try {
500 SomeArgs args = SomeArgs.obtain();
501 args.arg1 = callId;
502 args.arg2 = Log.createSubsession();
503 mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
504 } finally {
505 Log.endSession();
506 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700507 }
508
509 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700510 public void hold(String callId, Session.Info sessionInfo) {
511 Log.startSession(sessionInfo, SESSION_HOLD);
512 try {
513 SomeArgs args = SomeArgs.obtain();
514 args.arg1 = callId;
515 args.arg2 = Log.createSubsession();
516 mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
517 } finally {
518 Log.endSession();
519 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700520 }
521
522 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700523 public void unhold(String callId, Session.Info sessionInfo) {
524 Log.startSession(sessionInfo, SESSION_UNHOLD);
525 try {
526 SomeArgs args = SomeArgs.obtain();
527 args.arg1 = callId;
528 args.arg2 = Log.createSubsession();
529 mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
530 } finally {
531 Log.endSession();
532 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700533 }
534
535 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700536 public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
537 Session.Info sessionInfo) {
538 Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
539 try {
540 SomeArgs args = SomeArgs.obtain();
541 args.arg1 = callId;
542 args.arg2 = callAudioState;
543 args.arg3 = Log.createSubsession();
544 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
545 } finally {
546 Log.endSession();
547 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700548 }
549
550 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700551 public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
552 Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
553 try {
554 SomeArgs args = SomeArgs.obtain();
555 args.arg1 = digit;
556 args.arg2 = callId;
557 args.arg3 = Log.createSubsession();
558 mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, 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 stopDtmfTone(String callId, Session.Info sessionInfo) {
566 Log.startSession(sessionInfo, SESSION_STOP_DTMF);
567 try {
568 SomeArgs args = SomeArgs.obtain();
569 args.arg1 = callId;
570 args.arg2 = Log.createSubsession();
571 mHandler.obtainMessage(MSG_STOP_DTMF_TONE, 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 conference(String callId1, String callId2, Session.Info sessionInfo) {
579 Log.startSession(sessionInfo, SESSION_CONFERENCE);
580 try {
581 SomeArgs args = SomeArgs.obtain();
582 args.arg1 = callId1;
583 args.arg2 = callId2;
584 args.arg3 = Log.createSubsession();
585 mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
586 } finally {
587 Log.endSession();
588 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700589 }
590
591 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700592 public void splitFromConference(String callId, Session.Info sessionInfo) {
593 Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
594 try {
595 SomeArgs args = SomeArgs.obtain();
596 args.arg1 = callId;
597 args.arg2 = Log.createSubsession();
598 mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
599 } finally {
600 Log.endSession();
601 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700602 }
603
604 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700605 public void mergeConference(String callId, Session.Info sessionInfo) {
606 Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
607 try {
608 SomeArgs args = SomeArgs.obtain();
609 args.arg1 = callId;
610 args.arg2 = Log.createSubsession();
611 mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
612 } finally {
613 Log.endSession();
614 }
Santos Cordona4868042014-09-04 17:39:22 -0700615 }
616
617 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700618 public void swapConference(String callId, Session.Info sessionInfo) {
619 Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
620 try {
621 SomeArgs args = SomeArgs.obtain();
622 args.arg1 = callId;
623 args.arg2 = Log.createSubsession();
624 mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
625 } finally {
626 Log.endSession();
627 }
Santos Cordona4868042014-09-04 17:39:22 -0700628 }
629
630 @Override
Ravi Paluri404babb2020-01-23 19:02:44 +0530631 public void addConferenceParticipants(String callId, List<Uri> participants,
632 Session.Info sessionInfo) {
633 Log.startSession(sessionInfo, SESSION_ADD_PARTICIPANT);
634 try {
635 SomeArgs args = SomeArgs.obtain();
636 args.arg1 = callId;
637 args.arg2 = participants;
638 args.arg3 = Log.createSubsession();
639 mHandler.obtainMessage(MSG_ADD_PARTICIPANT, args).sendToTarget();
640 } finally {
641 Log.endSession();
642 }
643 }
644
645 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700646 public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
647 Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
648 try {
649 SomeArgs args = SomeArgs.obtain();
650 args.arg1 = callId;
651 args.arg2 = Log.createSubsession();
652 args.argi1 = proceed ? 1 : 0;
653 mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
654 } finally {
655 Log.endSession();
656 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700657 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700658
659 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700660 public void pullExternalCall(String callId, Session.Info sessionInfo) {
661 Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
662 try {
663 SomeArgs args = SomeArgs.obtain();
664 args.arg1 = callId;
665 args.arg2 = Log.createSubsession();
666 mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
667 } finally {
668 Log.endSession();
669 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700670 }
671
672 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700673 public void sendCallEvent(String callId, String event, Bundle extras,
674 Session.Info sessionInfo) {
675 Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
676 try {
677 SomeArgs args = SomeArgs.obtain();
678 args.arg1 = callId;
679 args.arg2 = event;
680 args.arg3 = extras;
681 args.arg4 = Log.createSubsession();
682 mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
683 } finally {
684 Log.endSession();
685 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700686 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700687
688 @Override
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700689 public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
690 Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
691 try {
692 SomeArgs args = SomeArgs.obtain();
693 args.arg1 = callId;
694 args.arg2 = extras;
695 args.arg3 = Log.createSubsession();
696 mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
697 } finally {
698 Log.endSession();
699 }
Tyler Gunndee56a82016-03-23 16:06:34 -0700700 }
Hall Liub64ac4c2017-02-06 10:49:48 -0800701
702 @Override
703 public void startRtt(String callId, ParcelFileDescriptor fromInCall,
704 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
705 Log.startSession(sessionInfo, SESSION_START_RTT);
706 try {
707 SomeArgs args = SomeArgs.obtain();
708 args.arg1 = callId;
709 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
710 args.arg3 = Log.createSubsession();
711 mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
712 } finally {
713 Log.endSession();
714 }
715 }
716
717 @Override
718 public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
719 Log.startSession(sessionInfo, SESSION_STOP_RTT);
720 try {
721 SomeArgs args = SomeArgs.obtain();
722 args.arg1 = callId;
723 args.arg2 = Log.createSubsession();
724 mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
725 } finally {
726 Log.endSession();
727 }
728 }
729
730 @Override
731 public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
732 ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
733 Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
734 try {
735 SomeArgs args = SomeArgs.obtain();
736 args.arg1 = callId;
737 if (toInCall == null || fromInCall == null) {
738 args.arg2 = null;
739 } else {
740 args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
741 }
742 args.arg3 = Log.createSubsession();
743 mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
744 } finally {
745 Log.endSession();
746 }
747 }
Pengquan Meng731c1a32017-11-21 18:01:13 -0800748
749 @Override
750 public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
751 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_LOST);
752 try {
753 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_LOST).sendToTarget();
754 } finally {
755 Log.endSession();
756 }
757 }
758
759 @Override
760 public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
761 Log.startSession(sessionInfo, SESSION_CONNECTION_SERVICE_FOCUS_GAINED);
762 try {
763 mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_GAINED).sendToTarget();
764 } finally {
765 Log.endSession();
766 }
767 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700768 };
769
770 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
771 @Override
772 public void handleMessage(Message msg) {
773 switch (msg.what) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700774 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
775 SomeArgs args = (SomeArgs) msg.obj;
776 try {
777 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
778 Log.continueSession((Session) args.arg2,
779 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
780 mAdapter.addAdapter(adapter);
781 onAdapterAttached();
782 } finally {
783 args.recycle();
784 Log.endSession();
785 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700786 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700787 }
788 case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
789 SomeArgs args = (SomeArgs) msg.obj;
790 try {
791 Log.continueSession((Session) args.arg2,
792 SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
793 mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
794 } finally {
795 args.recycle();
796 Log.endSession();
797 }
Ihab Awad8aecfed2014-08-08 17:06:11 -0700798 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700799 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700800 case MSG_CREATE_CONNECTION: {
801 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700802 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
Ihab Awadf8b69882014-07-25 15:14:01 -0700803 try {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700804 final PhoneAccountHandle connectionManagerPhoneAccount =
Ihab Awadf8b69882014-07-25 15:14:01 -0700805 (PhoneAccountHandle) args.arg1;
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700806 final String id = (String) args.arg2;
807 final ConnectionRequest request = (ConnectionRequest) args.arg3;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700808 final boolean isIncoming = args.argi1 == 1;
Yorke Leec3cf9822014-10-02 09:38:39 -0700809 final boolean isUnknown = args.argi2 == 1;
Ihab Awad5d0410f2014-07-30 10:07:40 -0700810 if (!mAreAccountsInitialized) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700811 Log.d(this, "Enqueueing pre-init request %s", id);
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700812 mPreInitializationConnectionRequests.add(
813 new android.telecom.Logging.Runnable(
814 SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
815 null /*lock*/) {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700816 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700817 public void loggedRun() {
Ihab Awad5d0410f2014-07-30 10:07:40 -0700818 createConnection(
819 connectionManagerPhoneAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700820 id,
Ihab Awad5d0410f2014-07-30 10:07:40 -0700821 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700822 isIncoming,
823 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700824 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -0700825 }.prepare());
Ihab Awad5d0410f2014-07-30 10:07:40 -0700826 } else {
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700827 createConnection(
828 connectionManagerPhoneAccount,
829 id,
830 request,
Yorke Leec3cf9822014-10-02 09:38:39 -0700831 isIncoming,
832 isUnknown);
Ihab Awad5d0410f2014-07-30 10:07:40 -0700833 }
Ihab Awadf8b69882014-07-25 15:14:01 -0700834 } finally {
835 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -0700836 Log.endSession();
Ihab Awadf8b69882014-07-25 15:14:01 -0700837 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -0700838 break;
Ihab Awadf8b69882014-07-25 15:14:01 -0700839 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -0700840 case MSG_CREATE_CONNECTION_COMPLETE: {
841 SomeArgs args = (SomeArgs) msg.obj;
842 Log.continueSession((Session) args.arg2,
843 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
844 try {
845 final String id = (String) args.arg1;
846 if (!mAreAccountsInitialized) {
847 Log.d(this, "Enqueueing pre-init request %s", id);
848 mPreInitializationConnectionRequests.add(
849 new android.telecom.Logging.Runnable(
850 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE
851 + ".pICR",
852 null /*lock*/) {
853 @Override
854 public void loggedRun() {
855 notifyCreateConnectionComplete(id);
856 }
857 }.prepare());
858 } else {
859 notifyCreateConnectionComplete(id);
860 }
861 } finally {
862 args.recycle();
863 Log.endSession();
864 }
865 break;
866 }
Tyler Gunn44e01912017-01-31 10:49:05 -0800867 case MSG_CREATE_CONNECTION_FAILED: {
868 SomeArgs args = (SomeArgs) msg.obj;
869 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
870 SESSION_CREATE_CONN_FAILED);
871 try {
872 final String id = (String) args.arg1;
873 final ConnectionRequest request = (ConnectionRequest) args.arg2;
874 final boolean isIncoming = args.argi1 == 1;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800875 final PhoneAccountHandle connectionMgrPhoneAccount =
876 (PhoneAccountHandle) args.arg4;
Tyler Gunn44e01912017-01-31 10:49:05 -0800877 if (!mAreAccountsInitialized) {
878 Log.d(this, "Enqueueing pre-init request %s", id);
879 mPreInitializationConnectionRequests.add(
880 new android.telecom.Logging.Runnable(
881 SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
882 null /*lock*/) {
883 @Override
884 public void loggedRun() {
Tyler Gunn159f35c2017-03-02 09:28:37 -0800885 createConnectionFailed(connectionMgrPhoneAccount, id,
886 request, isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800887 }
888 }.prepare());
889 } else {
890 Log.i(this, "createConnectionFailed %s", id);
Tyler Gunn159f35c2017-03-02 09:28:37 -0800891 createConnectionFailed(connectionMgrPhoneAccount, id, request,
892 isIncoming);
Tyler Gunn44e01912017-01-31 10:49:05 -0800893 }
894 } finally {
895 args.recycle();
896 Log.endSession();
897 }
898 break;
899 }
Ravi Paluri80aa2142019-12-02 11:57:37 +0530900 case MSG_CREATE_CONFERENCE: {
901 SomeArgs args = (SomeArgs) msg.obj;
902 Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
903 try {
904 final PhoneAccountHandle connectionManagerPhoneAccount =
905 (PhoneAccountHandle) args.arg1;
906 final String id = (String) args.arg2;
907 final ConnectionRequest request = (ConnectionRequest) args.arg3;
908 final boolean isIncoming = args.argi1 == 1;
909 final boolean isUnknown = args.argi2 == 1;
910 if (!mAreAccountsInitialized) {
911 Log.d(this, "Enqueueing pre-initconference request %s", id);
912 mPreInitializationConnectionRequests.add(
913 new android.telecom.Logging.Runnable(
914 SESSION_HANDLER + SESSION_CREATE_CONF + ".pIConfR",
915 null /*lock*/) {
916 @Override
917 public void loggedRun() {
918 createConference(connectionManagerPhoneAccount,
919 id,
920 request,
921 isIncoming,
922 isUnknown);
923 }
924 }.prepare());
925 } else {
926 createConference(connectionManagerPhoneAccount,
927 id,
928 request,
929 isIncoming,
930 isUnknown);
931 }
932 } finally {
933 args.recycle();
934 Log.endSession();
935 }
936 break;
937 }
938 case MSG_CREATE_CONFERENCE_COMPLETE: {
939 SomeArgs args = (SomeArgs) msg.obj;
940 Log.continueSession((Session) args.arg2,
941 SESSION_HANDLER + SESSION_CREATE_CONN_COMPLETE);
942 try {
943 final String id = (String) args.arg1;
944 if (!mAreAccountsInitialized) {
945 Log.d(this, "Enqueueing pre-init conference request %s", id);
946 mPreInitializationConnectionRequests.add(
947 new android.telecom.Logging.Runnable(
948 SESSION_HANDLER + SESSION_CREATE_CONF_COMPLETE
949 + ".pIConfR",
950 null /*lock*/) {
951 @Override
952 public void loggedRun() {
953 notifyCreateConferenceComplete(id);
954 }
955 }.prepare());
956 } else {
957 notifyCreateConferenceComplete(id);
958 }
959 } finally {
960 args.recycle();
961 Log.endSession();
962 }
963 break;
964 }
965 case MSG_CREATE_CONFERENCE_FAILED: {
966 SomeArgs args = (SomeArgs) msg.obj;
967 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
968 SESSION_CREATE_CONN_FAILED);
969 try {
970 final String id = (String) args.arg1;
971 final ConnectionRequest request = (ConnectionRequest) args.arg2;
972 final boolean isIncoming = args.argi1 == 1;
973 final PhoneAccountHandle connectionMgrPhoneAccount =
974 (PhoneAccountHandle) args.arg4;
975 if (!mAreAccountsInitialized) {
976 Log.d(this, "Enqueueing pre-init conference request %s", id);
977 mPreInitializationConnectionRequests.add(
978 new android.telecom.Logging.Runnable(
979 SESSION_HANDLER + SESSION_CREATE_CONF_FAILED
980 + ".pIConfR",
981 null /*lock*/) {
982 @Override
983 public void loggedRun() {
984 createConferenceFailed(connectionMgrPhoneAccount, id,
985 request, isIncoming);
986 }
987 }.prepare());
988 } else {
989 Log.i(this, "createConferenceFailed %s", id);
990 createConferenceFailed(connectionMgrPhoneAccount, id, request,
991 isIncoming);
992 }
993 } finally {
994 args.recycle();
995 Log.endSession();
996 }
997 break;
998 }
999
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001000 case MSG_HANDOVER_FAILED: {
1001 SomeArgs args = (SomeArgs) msg.obj;
1002 Log.continueSession((Session) args.arg3, SESSION_HANDLER +
1003 SESSION_HANDOVER_FAILED);
1004 try {
1005 final String id = (String) args.arg1;
1006 final ConnectionRequest request = (ConnectionRequest) args.arg2;
1007 final int reason = (int) args.arg4;
1008 if (!mAreAccountsInitialized) {
1009 Log.d(this, "Enqueueing pre-init request %s", id);
1010 mPreInitializationConnectionRequests.add(
1011 new android.telecom.Logging.Runnable(
1012 SESSION_HANDLER
1013 + SESSION_HANDOVER_FAILED + ".pICR",
1014 null /*lock*/) {
1015 @Override
1016 public void loggedRun() {
1017 handoverFailed(id, request, reason);
1018 }
1019 }.prepare());
1020 } else {
1021 Log.i(this, "createConnectionFailed %s", id);
1022 handoverFailed(id, request, reason);
1023 }
1024 } finally {
1025 args.recycle();
1026 Log.endSession();
1027 }
1028 break;
1029 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001030 case MSG_ABORT: {
1031 SomeArgs args = (SomeArgs) msg.obj;
1032 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
1033 try {
1034 abort((String) args.arg1);
1035 } finally {
1036 args.recycle();
1037 Log.endSession();
1038 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001039 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001040 }
1041 case MSG_ANSWER: {
1042 SomeArgs args = (SomeArgs) msg.obj;
1043 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
1044 try {
1045 answer((String) args.arg1);
1046 } finally {
1047 args.recycle();
1048 Log.endSession();
1049 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001050 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001051 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07001052 case MSG_ANSWER_VIDEO: {
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001053 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001054 Log.continueSession((Session) args.arg2,
1055 SESSION_HANDLER + SESSION_ANSWER_VIDEO);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001056 try {
1057 String callId = (String) args.arg1;
Evan Charltonbf11f982014-07-20 22:06:28 -07001058 int videoState = args.argi1;
Tyler Gunnbe74de02014-08-29 14:51:48 -07001059 answerVideo(callId, videoState);
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001060 } finally {
1061 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001062 Log.endSession();
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001063 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001064 break;
Andrew Lee8da4c3c2014-07-16 10:11:42 -07001065 }
Pooja Jaind34698d2017-12-28 14:15:31 +05301066 case MSG_DEFLECT: {
1067 SomeArgs args = (SomeArgs) msg.obj;
1068 Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
1069 try {
1070 deflect((String) args.arg1, (Uri) args.arg2);
1071 } finally {
1072 args.recycle();
1073 Log.endSession();
1074 }
1075 break;
1076 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001077 case MSG_REJECT: {
1078 SomeArgs args = (SomeArgs) msg.obj;
1079 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1080 try {
1081 reject((String) args.arg1);
1082 } finally {
1083 args.recycle();
1084 Log.endSession();
1085 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001086 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001087 }
Tyler Gunnfacfdee2020-01-23 13:10:37 -08001088 case MSG_REJECT_WITH_REASON: {
1089 SomeArgs args = (SomeArgs) msg.obj;
1090 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1091 try {
1092 reject((String) args.arg1, args.argi1);
1093 } finally {
1094 args.recycle();
1095 Log.endSession();
1096 }
1097 break;
1098 }
Bryce Lee81901682015-08-28 16:38:02 -07001099 case MSG_REJECT_WITH_MESSAGE: {
1100 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001101 Log.continueSession((Session) args.arg3,
1102 SESSION_HANDLER + SESSION_REJECT_MESSAGE);
Bryce Lee81901682015-08-28 16:38:02 -07001103 try {
1104 reject((String) args.arg1, (String) args.arg2);
1105 } finally {
1106 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001107 Log.endSession();
Bryce Lee81901682015-08-28 16:38:02 -07001108 }
1109 break;
1110 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001111 case MSG_DISCONNECT: {
1112 SomeArgs args = (SomeArgs) msg.obj;
1113 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
1114 try {
1115 disconnect((String) args.arg1);
1116 } finally {
1117 args.recycle();
1118 Log.endSession();
1119 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001120 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001121 }
1122 case MSG_SILENCE: {
1123 SomeArgs args = (SomeArgs) msg.obj;
1124 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
1125 try {
1126 silence((String) args.arg1);
1127 } finally {
1128 args.recycle();
1129 Log.endSession();
1130 }
Bryce Leecac50772015-11-17 15:13:29 -08001131 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001132 }
1133 case MSG_HOLD: {
1134 SomeArgs args = (SomeArgs) msg.obj;
1135 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
1136 try {
1137 hold((String) args.arg1);
1138 } finally {
1139 args.recycle();
1140 Log.endSession();
1141 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001142 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001143 }
1144 case MSG_UNHOLD: {
1145 SomeArgs args = (SomeArgs) msg.obj;
1146 Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
1147 try {
1148 unhold((String) args.arg1);
1149 } finally {
1150 args.recycle();
1151 Log.endSession();
1152 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001153 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001154 }
Yorke Lee4af59352015-05-13 14:14:54 -07001155 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001156 SomeArgs args = (SomeArgs) msg.obj;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001157 Log.continueSession((Session) args.arg3,
1158 SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001159 try {
1160 String callId = (String) args.arg1;
Yorke Lee4af59352015-05-13 14:14:54 -07001161 CallAudioState audioState = (CallAudioState) args.arg2;
1162 onCallAudioStateChanged(callId, new CallAudioState(audioState));
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001163 } finally {
1164 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001165 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001166 }
1167 break;
1168 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001169 case MSG_PLAY_DTMF_TONE: {
1170 SomeArgs args = (SomeArgs) msg.obj;
1171 try {
1172 Log.continueSession((Session) args.arg3,
1173 SESSION_HANDLER + SESSION_PLAY_DTMF);
1174 playDtmfTone((String) args.arg2, (char) args.arg1);
1175 } finally {
1176 args.recycle();
1177 Log.endSession();
1178 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001179 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001180 }
1181 case MSG_STOP_DTMF_TONE: {
1182 SomeArgs args = (SomeArgs) msg.obj;
1183 try {
1184 Log.continueSession((Session) args.arg2,
1185 SESSION_HANDLER + SESSION_STOP_DTMF);
1186 stopDtmfTone((String) args.arg1);
1187 } finally {
1188 args.recycle();
1189 Log.endSession();
1190 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001191 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001192 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001193 case MSG_CONFERENCE: {
1194 SomeArgs args = (SomeArgs) msg.obj;
1195 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001196 Log.continueSession((Session) args.arg3,
1197 SESSION_HANDLER + SESSION_CONFERENCE);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001198 String callId1 = (String) args.arg1;
1199 String callId2 = (String) args.arg2;
1200 conference(callId1, callId2);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001201 } finally {
1202 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001203 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001204 }
1205 break;
1206 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001207 case MSG_SPLIT_FROM_CONFERENCE: {
1208 SomeArgs args = (SomeArgs) msg.obj;
1209 try {
1210 Log.continueSession((Session) args.arg2,
1211 SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
1212 splitFromConference((String) args.arg1);
1213 } finally {
1214 args.recycle();
1215 Log.endSession();
1216 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001217 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001218 }
1219 case MSG_MERGE_CONFERENCE: {
1220 SomeArgs args = (SomeArgs) msg.obj;
1221 try {
1222 Log.continueSession((Session) args.arg2,
1223 SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
1224 mergeConference((String) args.arg1);
1225 } finally {
1226 args.recycle();
1227 Log.endSession();
1228 }
Santos Cordona4868042014-09-04 17:39:22 -07001229 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001230 }
1231 case MSG_SWAP_CONFERENCE: {
1232 SomeArgs args = (SomeArgs) msg.obj;
1233 try {
1234 Log.continueSession((Session) args.arg2,
1235 SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
1236 swapConference((String) args.arg1);
1237 } finally {
1238 args.recycle();
1239 Log.endSession();
1240 }
Santos Cordona4868042014-09-04 17:39:22 -07001241 break;
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001242 }
Ravi Paluri404babb2020-01-23 19:02:44 +05301243 case MSG_ADD_PARTICIPANT: {
1244 SomeArgs args = (SomeArgs) msg.obj;
1245 try {
1246 Log.continueSession((Session) args.arg3,
1247 SESSION_HANDLER + SESSION_ADD_PARTICIPANT);
1248 addConferenceParticipants((String) args.arg1, (List<Uri>)args.arg2);
1249 } finally {
1250 args.recycle();
1251 Log.endSession();
1252 }
1253 break;
1254 }
1255
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001256 case MSG_ON_POST_DIAL_CONTINUE: {
1257 SomeArgs args = (SomeArgs) msg.obj;
1258 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001259 Log.continueSession((Session) args.arg2,
1260 SESSION_HANDLER + SESSION_POST_DIAL_CONT);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001261 String callId = (String) args.arg1;
1262 boolean proceed = (args.argi1 == 1);
1263 onPostDialContinue(callId, proceed);
1264 } finally {
1265 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001266 Log.endSession();
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001267 }
1268 break;
1269 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001270 case MSG_PULL_EXTERNAL_CALL: {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001271 SomeArgs args = (SomeArgs) msg.obj;
1272 try {
1273 Log.continueSession((Session) args.arg2,
1274 SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
1275 pullExternalCall((String) args.arg1);
1276 } finally {
1277 args.recycle();
1278 Log.endSession();
1279 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001280 break;
1281 }
1282 case MSG_SEND_CALL_EVENT: {
1283 SomeArgs args = (SomeArgs) msg.obj;
1284 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001285 Log.continueSession((Session) args.arg4,
1286 SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001287 String callId = (String) args.arg1;
1288 String event = (String) args.arg2;
1289 Bundle extras = (Bundle) args.arg3;
1290 sendCallEvent(callId, event, extras);
1291 } finally {
1292 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001293 Log.endSession();
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001294 }
1295 break;
1296 }
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001297 case MSG_HANDOVER_COMPLETE: {
1298 SomeArgs args = (SomeArgs) msg.obj;
1299 try {
1300 Log.continueSession((Session) args.arg2,
1301 SESSION_HANDLER + SESSION_HANDOVER_COMPLETE);
1302 String callId = (String) args.arg1;
1303 notifyHandoverComplete(callId);
1304 } finally {
1305 args.recycle();
1306 Log.endSession();
1307 }
1308 break;
1309 }
Tyler Gunndee56a82016-03-23 16:06:34 -07001310 case MSG_ON_EXTRAS_CHANGED: {
1311 SomeArgs args = (SomeArgs) msg.obj;
1312 try {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001313 Log.continueSession((Session) args.arg3,
1314 SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
Tyler Gunndee56a82016-03-23 16:06:34 -07001315 String callId = (String) args.arg1;
1316 Bundle extras = (Bundle) args.arg2;
1317 handleExtrasChanged(callId, extras);
1318 } finally {
1319 args.recycle();
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001320 Log.endSession();
Tyler Gunndee56a82016-03-23 16:06:34 -07001321 }
1322 break;
1323 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001324 case MSG_ON_START_RTT: {
1325 SomeArgs args = (SomeArgs) msg.obj;
1326 try {
1327 Log.continueSession((Session) args.arg3,
1328 SESSION_HANDLER + SESSION_START_RTT);
1329 String callId = (String) args.arg1;
1330 Connection.RttTextStream rttTextStream =
1331 (Connection.RttTextStream) args.arg2;
1332 startRtt(callId, rttTextStream);
1333 } finally {
1334 args.recycle();
1335 Log.endSession();
1336 }
1337 break;
1338 }
1339 case MSG_ON_STOP_RTT: {
1340 SomeArgs args = (SomeArgs) msg.obj;
1341 try {
1342 Log.continueSession((Session) args.arg2,
1343 SESSION_HANDLER + SESSION_STOP_RTT);
1344 String callId = (String) args.arg1;
1345 stopRtt(callId);
1346 } finally {
1347 args.recycle();
1348 Log.endSession();
1349 }
1350 break;
1351 }
1352 case MSG_RTT_UPGRADE_RESPONSE: {
1353 SomeArgs args = (SomeArgs) msg.obj;
1354 try {
1355 Log.continueSession((Session) args.arg3,
1356 SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
1357 String callId = (String) args.arg1;
1358 Connection.RttTextStream rttTextStream =
1359 (Connection.RttTextStream) args.arg2;
1360 handleRttUpgradeResponse(callId, rttTextStream);
1361 } finally {
1362 args.recycle();
1363 Log.endSession();
1364 }
1365 break;
1366 }
Pengquan Meng731c1a32017-11-21 18:01:13 -08001367 case MSG_CONNECTION_SERVICE_FOCUS_GAINED:
1368 onConnectionServiceFocusGained();
1369 break;
1370 case MSG_CONNECTION_SERVICE_FOCUS_LOST:
1371 onConnectionServiceFocusLost();
1372 break;
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001373 default:
1374 break;
1375 }
1376 }
1377 };
1378
Santos Cordon823fd3c2014-08-07 18:35:18 -07001379 private final Conference.Listener mConferenceListener = new Conference.Listener() {
1380 @Override
1381 public void onStateChanged(Conference conference, int oldState, int newState) {
1382 String id = mIdByConference.get(conference);
1383 switch (newState) {
Ravi Paluri80aa2142019-12-02 11:57:37 +05301384 case Connection.STATE_RINGING:
1385 mAdapter.setRinging(id);
1386 break;
1387 case Connection.STATE_DIALING:
1388 mAdapter.setDialing(id);
1389 break;
Santos Cordon823fd3c2014-08-07 18:35:18 -07001390 case Connection.STATE_ACTIVE:
1391 mAdapter.setActive(id);
1392 break;
1393 case Connection.STATE_HOLDING:
1394 mAdapter.setOnHold(id);
1395 break;
1396 case Connection.STATE_DISCONNECTED:
1397 // handled by onDisconnected
1398 break;
1399 }
1400 }
1401
1402 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001403 public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001404 String id = mIdByConference.get(conference);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001405 mAdapter.setDisconnected(id, disconnectCause);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001406 }
1407
1408 @Override
1409 public void onConnectionAdded(Conference conference, Connection connection) {
1410 }
1411
1412 @Override
1413 public void onConnectionRemoved(Conference conference, Connection connection) {
1414 }
1415
1416 @Override
Ihab Awad50e35062014-09-30 09:17:03 -07001417 public void onConferenceableConnectionsChanged(
1418 Conference conference, List<Connection> conferenceableConnections) {
1419 mAdapter.setConferenceableConnections(
1420 mIdByConference.get(conference),
1421 createConnectionIdList(conferenceableConnections));
1422 }
1423
1424 @Override
Santos Cordon823fd3c2014-08-07 18:35:18 -07001425 public void onDestroyed(Conference conference) {
1426 removeConference(conference);
1427 }
1428
1429 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001430 public void onConnectionCapabilitiesChanged(
1431 Conference conference,
1432 int connectionCapabilities) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07001433 String id = mIdByConference.get(conference);
1434 Log.d(this, "call capabilities: conference: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001435 Connection.capabilitiesToString(connectionCapabilities));
1436 mAdapter.setConnectionCapabilities(id, connectionCapabilities);
Santos Cordon823fd3c2014-08-07 18:35:18 -07001437 }
Rekha Kumar07366812015-03-24 16:42:31 -07001438
1439 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001440 public void onConnectionPropertiesChanged(
1441 Conference conference,
1442 int connectionProperties) {
1443 String id = mIdByConference.get(conference);
1444 Log.d(this, "call capabilities: conference: %s",
1445 Connection.propertiesToString(connectionProperties));
1446 mAdapter.setConnectionProperties(id, connectionProperties);
1447 }
1448
1449 @Override
Rekha Kumar07366812015-03-24 16:42:31 -07001450 public void onVideoStateChanged(Conference c, int videoState) {
1451 String id = mIdByConference.get(c);
1452 Log.d(this, "onVideoStateChanged set video state %d", videoState);
1453 mAdapter.setVideoState(id, videoState);
1454 }
1455
1456 @Override
1457 public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {
1458 String id = mIdByConference.get(c);
1459 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1460 videoProvider);
1461 mAdapter.setVideoProvider(id, videoProvider);
1462 }
Andrew Lee0f51da32015-04-16 13:11:55 -07001463
1464 @Override
Andrew Leeedc625f2015-04-14 13:38:12 -07001465 public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
1466 String id = mIdByConference.get(conference);
Tyler Gunndee56a82016-03-23 16:06:34 -07001467 if (id != null) {
1468 mAdapter.setStatusHints(id, statusHints);
1469 }
Andrew Leeedc625f2015-04-14 13:38:12 -07001470 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001471
1472 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001473 public void onExtrasChanged(Conference c, Bundle extras) {
1474 String id = mIdByConference.get(c);
1475 if (id != null) {
1476 mAdapter.putExtras(id, extras);
1477 }
1478 }
1479
1480 @Override
1481 public void onExtrasRemoved(Conference c, List<String> keys) {
1482 String id = mIdByConference.get(c);
1483 if (id != null) {
1484 mAdapter.removeExtras(id, keys);
1485 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001486 }
Tyler Gunn68a73a42018-10-03 15:38:57 -07001487
1488 @Override
1489 public void onConferenceStateChanged(Conference c, boolean isConference) {
1490 String id = mIdByConference.get(c);
1491 if (id != null) {
1492 mAdapter.setConferenceState(id, isConference);
1493 }
1494 }
1495
1496 @Override
1497 public void onAddressChanged(Conference c, Uri newAddress, int presentation) {
1498 String id = mIdByConference.get(c);
1499 if (id != null) {
1500 mAdapter.setAddress(id, newAddress, presentation);
1501 }
1502 }
1503
1504 @Override
1505 public void onCallerDisplayNameChanged(Conference c, String callerDisplayName,
1506 int presentation) {
1507 String id = mIdByConference.get(c);
1508 if (id != null) {
1509 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
1510 }
1511 }
Hall Liuc9bc1c62019-04-16 14:00:55 -07001512
1513 @Override
1514 public void onConnectionEvent(Conference c, String event, Bundle extras) {
1515 String id = mIdByConference.get(c);
1516 if (id != null) {
1517 mAdapter.onConnectionEvent(id, event, extras);
1518 }
1519 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05301520
1521 @Override
1522 public void onRingbackRequested(Conference c, boolean ringback) {
1523 String id = mIdByConference.get(c);
1524 Log.d(this, "Adapter conference onRingback %b", ringback);
1525 mAdapter.setRingbackRequested(id, ringback);
1526 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001527 };
1528
Ihab Awad542e0ea2014-05-16 10:22:16 -07001529 private final Connection.Listener mConnectionListener = new Connection.Listener() {
1530 @Override
1531 public void onStateChanged(Connection c, int state) {
1532 String id = mIdByConnection.get(c);
Ihab Awad42b30e12014-05-22 09:49:34 -07001533 Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
Ihab Awad542e0ea2014-05-16 10:22:16 -07001534 switch (state) {
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001535 case Connection.STATE_ACTIVE:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001536 mAdapter.setActive(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001537 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001538 case Connection.STATE_DIALING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001539 mAdapter.setDialing(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001540 break;
Tyler Gunnc96b5e02016-07-07 22:53:57 -07001541 case Connection.STATE_PULLING_CALL:
1542 mAdapter.setPulling(id);
1543 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001544 case Connection.STATE_DISCONNECTED:
Ihab Awad542e0ea2014-05-16 10:22:16 -07001545 // Handled in onDisconnected()
1546 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001547 case Connection.STATE_HOLDING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001548 mAdapter.setOnHold(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001549 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001550 case Connection.STATE_NEW:
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001551 // Nothing to tell Telecom
Ihab Awad542e0ea2014-05-16 10:22:16 -07001552 break;
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001553 case Connection.STATE_RINGING:
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001554 mAdapter.setRinging(id);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001555 break;
1556 }
1557 }
1558
1559 @Override
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001560 public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07001561 String id = mIdByConnection.get(c);
Andrew Lee26786392014-09-16 18:14:59 -07001562 Log.d(this, "Adapter set disconnected %s", disconnectCause);
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001563 mAdapter.setDisconnected(id, disconnectCause);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001564 }
1565
1566 @Override
Tyler Gunnaa07df82014-07-17 07:50:22 -07001567 public void onVideoStateChanged(Connection c, int videoState) {
1568 String id = mIdByConnection.get(c);
1569 Log.d(this, "Adapter set video state %d", videoState);
1570 mAdapter.setVideoState(id, videoState);
1571 }
1572
1573 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001574 public void onAddressChanged(Connection c, Uri address, int presentation) {
Sailesh Nepal61203862014-07-11 14:50:13 -07001575 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001576 mAdapter.setAddress(id, address, presentation);
Sailesh Nepal61203862014-07-11 14:50:13 -07001577 }
1578
1579 @Override
1580 public void onCallerDisplayNameChanged(
1581 Connection c, String callerDisplayName, int presentation) {
1582 String id = mIdByConnection.get(c);
1583 mAdapter.setCallerDisplayName(id, callerDisplayName, presentation);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001584 }
1585
1586 @Override
Ihab Awad542e0ea2014-05-16 10:22:16 -07001587 public void onDestroyed(Connection c) {
1588 removeConnection(c);
1589 }
Ihab Awadf8358972014-05-28 16:46:42 -07001590
1591 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001592 public void onPostDialWait(Connection c, String remaining) {
Sailesh Nepal091768c2014-06-30 15:15:23 -07001593 String id = mIdByConnection.get(c);
1594 Log.d(this, "Adapter onPostDialWait %s, %s", c, remaining);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001595 mAdapter.onPostDialWait(id, remaining);
Sailesh Nepal091768c2014-06-30 15:15:23 -07001596 }
1597
1598 @Override
Nancy Chen27d1c2d2014-12-15 16:12:50 -08001599 public void onPostDialChar(Connection c, char nextChar) {
1600 String id = mIdByConnection.get(c);
1601 Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
1602 mAdapter.onPostDialChar(id, nextChar);
1603 }
1604
1605 @Override
Andrew Lee100e2932014-09-08 15:34:24 -07001606 public void onRingbackRequested(Connection c, boolean ringback) {
Ihab Awadf8358972014-05-28 16:46:42 -07001607 String id = mIdByConnection.get(c);
1608 Log.d(this, "Adapter onRingback %b", ringback);
Andrew Lee100e2932014-09-08 15:34:24 -07001609 mAdapter.setRingbackRequested(id, ringback);
Ihab Awadf8358972014-05-28 16:46:42 -07001610 }
Santos Cordonb6939982014-06-04 20:20:58 -07001611
1612 @Override
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001613 public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {
Santos Cordonb6939982014-06-04 20:20:58 -07001614 String id = mIdByConnection.get(c);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001615 Log.d(this, "capabilities: parcelableconnection: %s",
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001616 Connection.capabilitiesToString(capabilities));
1617 mAdapter.setConnectionCapabilities(id, capabilities);
Santos Cordonb6939982014-06-04 20:20:58 -07001618 }
1619
Santos Cordonb6939982014-06-04 20:20:58 -07001620 @Override
Tyler Gunn720c6642016-03-22 09:02:47 -07001621 public void onConnectionPropertiesChanged(Connection c, int properties) {
1622 String id = mIdByConnection.get(c);
1623 Log.d(this, "properties: parcelableconnection: %s",
1624 Connection.propertiesToString(properties));
1625 mAdapter.setConnectionProperties(id, properties);
1626 }
1627
1628 @Override
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001629 public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001630 String id = mIdByConnection.get(c);
Rekha Kumar07366812015-03-24 16:42:31 -07001631 Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
1632 videoProvider);
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001633 mAdapter.setVideoProvider(id, videoProvider);
Andrew Lee5ffbe8b82014-06-20 16:29:33 -07001634 }
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001635
1636 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001637 public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001638 String id = mIdByConnection.get(c);
Andrew Lee100e2932014-09-08 15:34:24 -07001639 mAdapter.setIsVoipAudioMode(id, isVoip);
Sailesh Nepal33aaae42014-07-07 22:49:44 -07001640 }
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001641
1642 @Override
Sailesh Nepal001bbbb2014-07-15 14:40:39 -07001643 public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
Sailesh Nepale7ef59a2014-07-08 21:48:22 -07001644 String id = mIdByConnection.get(c);
1645 mAdapter.setStatusHints(id, statusHints);
1646 }
Sailesh Nepal2ab88cc2014-07-18 14:49:18 -07001647
1648 @Override
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001649 public void onConferenceablesChanged(
Tyler Gunndf2cbc82015-04-20 09:13:01 -07001650 Connection connection, List<Conferenceable> conferenceables) {
Ihab Awadb8e85c72014-08-23 20:34:57 -07001651 mAdapter.setConferenceableConnections(
1652 mIdByConnection.get(connection),
Tyler Gunn6d76ca02014-11-17 15:49:51 -08001653 createIdList(conferenceables));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001654 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07001655
1656 @Override
1657 public void onConferenceChanged(Connection connection, Conference conference) {
1658 String id = mIdByConnection.get(connection);
1659 if (id != null) {
1660 String conferenceId = null;
1661 if (conference != null) {
1662 conferenceId = mIdByConference.get(conference);
1663 }
1664 mAdapter.setIsConferenced(id, conferenceId);
1665 }
1666 }
Anthony Lee17455a32015-04-24 15:25:29 -07001667
1668 @Override
1669 public void onConferenceMergeFailed(Connection connection) {
1670 String id = mIdByConnection.get(connection);
1671 if (id != null) {
1672 mAdapter.onConferenceMergeFailed(id);
1673 }
1674 }
Santos Cordon6b7f9552015-05-27 17:21:45 -07001675
1676 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001677 public void onExtrasChanged(Connection c, Bundle extras) {
1678 String id = mIdByConnection.get(c);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001679 if (id != null) {
Tyler Gunndee56a82016-03-23 16:06:34 -07001680 mAdapter.putExtras(id, extras);
Santos Cordon6b7f9552015-05-27 17:21:45 -07001681 }
1682 }
Brad Ebingerb32d4f82016-10-24 16:40:49 -07001683
Tyler Gunnf5035432017-01-09 09:43:12 -08001684 @Override
Tyler Gunndee56a82016-03-23 16:06:34 -07001685 public void onExtrasRemoved(Connection c, List<String> keys) {
1686 String id = mIdByConnection.get(c);
1687 if (id != null) {
1688 mAdapter.removeExtras(id, keys);
1689 }
1690 }
1691
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001692 @Override
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001693 public void onConnectionEvent(Connection connection, String event, Bundle extras) {
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001694 String id = mIdByConnection.get(connection);
1695 if (id != null) {
Tyler Gunn876dbfb2016-03-14 15:18:07 -07001696 mAdapter.onConnectionEvent(id, event, extras);
Tyler Gunnbd1eb1f2016-02-16 14:36:20 -08001697 }
1698 }
Tyler Gunnf5035432017-01-09 09:43:12 -08001699
1700 @Override
Hall Liua98f58b52017-11-07 17:59:28 -08001701 public void onAudioRouteChanged(Connection c, int audioRoute, String bluetoothAddress) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001702 String id = mIdByConnection.get(c);
1703 if (id != null) {
Hall Liua98f58b52017-11-07 17:59:28 -08001704 mAdapter.setAudioRoute(id, audioRoute, bluetoothAddress);
Tyler Gunnf5035432017-01-09 09:43:12 -08001705 }
1706 }
Hall Liub64ac4c2017-02-06 10:49:48 -08001707
1708 @Override
1709 public void onRttInitiationSuccess(Connection c) {
1710 String id = mIdByConnection.get(c);
1711 if (id != null) {
1712 mAdapter.onRttInitiationSuccess(id);
1713 }
1714 }
1715
1716 @Override
1717 public void onRttInitiationFailure(Connection c, int reason) {
1718 String id = mIdByConnection.get(c);
1719 if (id != null) {
1720 mAdapter.onRttInitiationFailure(id, reason);
1721 }
1722 }
1723
1724 @Override
1725 public void onRttSessionRemotelyTerminated(Connection c) {
1726 String id = mIdByConnection.get(c);
1727 if (id != null) {
1728 mAdapter.onRttSessionRemotelyTerminated(id);
1729 }
1730 }
1731
1732 @Override
1733 public void onRemoteRttRequest(Connection c) {
1734 String id = mIdByConnection.get(c);
1735 if (id != null) {
1736 mAdapter.onRemoteRttRequest(id);
1737 }
1738 }
Srikanth Chintalafcb15012017-05-04 20:58:34 +05301739
1740 @Override
1741 public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {
1742 String id = mIdByConnection.get(c);
1743 if (id != null) {
1744 mAdapter.onPhoneAccountChanged(id, pHandle);
1745 }
1746 }
Mengjun Leng25707742017-07-04 11:10:37 +08001747
1748 public void onConnectionTimeReset(Connection c) {
1749 String id = mIdByConnection.get(c);
1750 if (id != null) {
1751 mAdapter.resetConnectionTime(id);
1752 }
1753 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001754 };
1755
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001756 /** {@inheritDoc} */
Ihab Awad542e0ea2014-05-16 10:22:16 -07001757 @Override
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001758 public final IBinder onBind(Intent intent) {
1759 return mBinder;
1760 }
1761
Santos Cordon29f2f2e2014-09-11 19:50:24 -07001762 /** {@inheritDoc} */
1763 @Override
1764 public boolean onUnbind(Intent intent) {
1765 endAllConnections();
1766 return super.onUnbind(intent);
1767 }
1768
Ravi Paluri80aa2142019-12-02 11:57:37 +05301769
1770 /**
1771 * This can be used by telecom to either create a new outgoing conference call or attach
1772 * to an existing incoming conference call. In either case, telecom will cycle through a
1773 * set of services and call createConference until a connection service cancels the process
1774 * or completes it successfully.
1775 */
1776 private void createConference(
1777 final PhoneAccountHandle callManagerAccount,
1778 final String callId,
1779 final ConnectionRequest request,
1780 boolean isIncoming,
1781 boolean isUnknown) {
1782
1783 Conference conference = null;
1784 conference = isIncoming ? onCreateIncomingConference(callManagerAccount, request)
1785 : onCreateOutgoingConference(callManagerAccount, request);
1786
1787 Log.d(this, "createConference, conference: %s", conference);
1788 if (conference == null) {
1789 Log.i(this, "createConference, implementation returned null conference.");
1790 conference = Conference.createFailedConference(
1791 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONFERENCE"),
1792 request.getAccountHandle());
1793 }
1794 if (conference.getExtras() != null) {
1795 conference.getExtras().putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
1796 }
1797 mConferenceById.put(callId, conference);
1798 mIdByConference.put(conference, callId);
1799 conference.addListener(mConferenceListener);
1800 ParcelableConference parcelableConference = new ParcelableConference(
1801 request.getAccountHandle(),
1802 conference.getState(),
1803 conference.getConnectionCapabilities(),
1804 conference.getConnectionProperties(),
1805 Collections.<String>emptyList(), //connectionIds
1806 conference.getVideoProvider() == null ?
1807 null : conference.getVideoProvider().getInterface(),
1808 conference.getVideoState(),
1809 conference.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08001810 conference.getConnectionStartElapsedRealtimeMillis(),
Ravi Paluri80aa2142019-12-02 11:57:37 +05301811 conference.getStatusHints(),
1812 conference.getExtras(),
1813 conference.getAddress(),
1814 conference.getAddressPresentation(),
1815 conference.getCallerDisplayName(),
1816 conference.getCallerDisplayNamePresentation(),
1817 conference.getDisconnectCause(),
1818 conference.isRingbackRequested());
1819 if (conference.getState() != Connection.STATE_DISCONNECTED) {
1820 conference.setTelecomCallId(callId);
1821 mAdapter.setVideoProvider(callId, conference.getVideoProvider());
1822 mAdapter.setVideoState(callId, conference.getVideoState());
1823 onConferenceAdded(conference);
1824 }
1825
1826 Log.d(this, "createConference, calling handleCreateConferenceSuccessful %s", callId);
1827 mAdapter.handleCreateConferenceComplete(
1828 callId,
1829 request,
1830 parcelableConference);
1831 }
1832
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001833 /**
Tyler Gunnef9f6f92014-09-12 22:16:17 -07001834 * This can be used by telecom to either create a new outgoing call or attach to an existing
1835 * incoming call. In either case, telecom will cycle through a set of services and call
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001836 * createConnection util a connection service cancels the process or completes it successfully.
1837 */
Ihab Awadf8b69882014-07-25 15:14:01 -07001838 private void createConnection(
1839 final PhoneAccountHandle callManagerAccount,
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001840 final String callId,
Ihab Awadf8b69882014-07-25 15:14:01 -07001841 final ConnectionRequest request,
Yorke Leec3cf9822014-10-02 09:38:39 -07001842 boolean isIncoming,
1843 boolean isUnknown) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001844 boolean isLegacyHandover = request.getExtras() != null &&
1845 request.getExtras().getBoolean(TelecomManager.EXTRA_IS_HANDOVER, false);
1846 boolean isHandover = request.getExtras() != null && request.getExtras().getBoolean(
1847 TelecomManager.EXTRA_IS_HANDOVER_CONNECTION, false);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001848 Log.d(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, " +
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001849 "isIncoming: %b, isUnknown: %b, isLegacyHandover: %b, isHandover: %b",
1850 callManagerAccount, callId, request, isIncoming, isUnknown, isLegacyHandover,
1851 isHandover);
Ihab Awad542e0ea2014-05-16 10:22:16 -07001852
Sanket Padawee29a2662017-12-01 13:59:27 -08001853 Connection connection = null;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001854 if (isHandover) {
1855 PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
1856 ? (PhoneAccountHandle) request.getExtras().getParcelable(
1857 TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
Sanket Padawee29a2662017-12-01 13:59:27 -08001858 if (!isIncoming) {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001859 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08001860 } else {
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001861 connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
Sanket Padawee29a2662017-12-01 13:59:27 -08001862 }
1863 } else {
1864 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
1865 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
1866 : onCreateOutgoingConnection(callManagerAccount, request);
1867 }
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001868 Log.d(this, "createConnection, connection: %s", connection);
1869 if (connection == null) {
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08001870 Log.i(this, "createConnection, implementation returned null connection.");
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001871 connection = Connection.createFailedConnection(
Tyler Gunnfba1a8e2017-12-19 15:23:59 -08001872 new DisconnectCause(DisconnectCause.ERROR, "IMPL_RETURNED_NULL_CONNECTION"));
Sailesh Nepalc5b01572014-07-14 16:29:44 -07001873 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07001874
Tyler Gunnf2e08b42018-05-24 10:44:44 -07001875 boolean isSelfManaged =
1876 (connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED)
1877 == Connection.PROPERTY_SELF_MANAGED;
1878 // Self-managed Connections should always use voip audio mode; we default here so that the
1879 // local state within the ConnectionService matches the default we assume in Telecom.
1880 if (isSelfManaged) {
1881 connection.setAudioModeIsVoip(true);
1882 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07001883 connection.setTelecomCallId(callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001884 if (connection.getState() != Connection.STATE_DISCONNECTED) {
Pengquan Meng70c9885332017-10-02 18:09:03 -07001885 addConnection(request.getAccountHandle(), callId, connection);
Ihab Awad6107bab2014-08-18 09:23:25 -07001886 }
1887
Andrew Lee100e2932014-09-08 15:34:24 -07001888 Uri address = connection.getAddress();
1889 String number = address == null ? "null" : address.getSchemeSpecificPart();
Tyler Gunn720c6642016-03-22 09:02:47 -07001890 Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001891 Connection.toLogSafePhoneNumber(number),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001892 Connection.stateToString(connection.getState()),
Tyler Gunn720c6642016-03-22 09:02:47 -07001893 Connection.capabilitiesToString(connection.getConnectionCapabilities()),
1894 Connection.propertiesToString(connection.getConnectionProperties()));
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07001895
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001896 Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
Ihab Awad6107bab2014-08-18 09:23:25 -07001897 mAdapter.handleCreateConnectionComplete(
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001898 callId,
Evan Charltonbf11f982014-07-20 22:06:28 -07001899 request,
1900 new ParcelableConnection(
1901 request.getAccountHandle(),
1902 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08001903 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07001904 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08001905 connection.getSupportedAudioRoutes(),
Andrew Lee100e2932014-09-08 15:34:24 -07001906 connection.getAddress(),
1907 connection.getAddressPresentation(),
Evan Charltonbf11f982014-07-20 22:06:28 -07001908 connection.getCallerDisplayName(),
1909 connection.getCallerDisplayNamePresentation(),
Ihab Awadb19a0bc2014-08-07 19:46:01 -07001910 connection.getVideoProvider() == null ?
1911 null : connection.getVideoProvider().getInterface(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07001912 connection.getVideoState(),
Andrew Lee100e2932014-09-08 15:34:24 -07001913 connection.isRingbackRequested(),
Sailesh Nepal8b9d3ca2014-08-14 17:39:34 -07001914 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07001915 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08001916 connection.getConnectionStartElapsedRealtimeMillis(),
Ihab Awad6107bab2014-08-18 09:23:25 -07001917 connection.getStatusHints(),
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07001918 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07001919 createIdList(connection.getConferenceables()),
Tyler Gunnd57d76c2019-09-24 14:53:23 -07001920 connection.getExtras(),
1921 connection.getCallerNumberVerificationStatus()));
Tyler Gunnf5035432017-01-09 09:43:12 -08001922
Tyler Gunnf2e08b42018-05-24 10:44:44 -07001923 if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
Tyler Gunnf5035432017-01-09 09:43:12 -08001924 // Tell ConnectionService to show its incoming call UX.
1925 connection.onShowIncomingCallUi();
1926 }
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08001927 if (isUnknown) {
1928 triggerConferenceRecalculate();
1929 }
Evan Charltonbf11f982014-07-20 22:06:28 -07001930 }
1931
Tyler Gunn159f35c2017-03-02 09:28:37 -08001932 private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
1933 final String callId, final ConnectionRequest request,
1934 boolean isIncoming) {
Tyler Gunn44e01912017-01-31 10:49:05 -08001935
1936 Log.i(this, "createConnectionFailed %s", callId);
1937 if (isIncoming) {
Tyler Gunn159f35c2017-03-02 09:28:37 -08001938 onCreateIncomingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08001939 } else {
Tyler Gunn159f35c2017-03-02 09:28:37 -08001940 onCreateOutgoingConnectionFailed(callManagerAccount, request);
Tyler Gunn44e01912017-01-31 10:49:05 -08001941 }
1942 }
1943
Ravi Paluri80aa2142019-12-02 11:57:37 +05301944 private void createConferenceFailed(final PhoneAccountHandle callManagerAccount,
1945 final String callId, final ConnectionRequest request,
1946 boolean isIncoming) {
1947
1948 Log.i(this, "createConferenceFailed %s", callId);
1949 if (isIncoming) {
1950 onCreateIncomingConferenceFailed(callManagerAccount, request);
1951 } else {
1952 onCreateOutgoingConferenceFailed(callManagerAccount, request);
1953 }
1954 }
1955
Sanket Padawe4cc8ed52017-12-04 16:22:20 -08001956 private void handoverFailed(final String callId, final ConnectionRequest request,
1957 int reason) {
1958
1959 Log.i(this, "handoverFailed %s", callId);
1960 onHandoverFailed(request, reason);
1961 }
1962
Tyler Gunn041a1fe2017-05-12 10:04:49 -07001963 /**
1964 * Called by Telecom when the creation of a new Connection has completed and it is now added
1965 * to Telecom.
1966 * @param callId The ID of the connection.
1967 */
1968 private void notifyCreateConnectionComplete(final String callId) {
1969 Log.i(this, "notifyCreateConnectionComplete %s", callId);
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07001970 if (callId == null) {
1971 // This could happen if the connection fails quickly and is removed from the
1972 // ConnectionService before Telecom sends the create connection complete callback.
1973 Log.w(this, "notifyCreateConnectionComplete: callId is null.");
1974 return;
1975 }
Tyler Gunn041a1fe2017-05-12 10:04:49 -07001976 onCreateConnectionComplete(findConnectionForAction(callId,
1977 "notifyCreateConnectionComplete"));
1978 }
1979
Ravi Paluri80aa2142019-12-02 11:57:37 +05301980 /**
1981 * Called by Telecom when the creation of a new Conference has completed and it is now added
1982 * to Telecom.
1983 * @param callId The ID of the connection.
1984 */
1985 private void notifyCreateConferenceComplete(final String callId) {
1986 Log.i(this, "notifyCreateConferenceComplete %s", callId);
1987 if (callId == null) {
1988 // This could happen if the conference fails quickly and is removed from the
1989 // ConnectionService before Telecom sends the create conference complete callback.
1990 Log.w(this, "notifyCreateConferenceComplete: callId is null.");
1991 return;
1992 }
1993 onCreateConferenceComplete(findConferenceForAction(callId,
1994 "notifyCreateConferenceComplete"));
1995 }
1996
1997
Sailesh Nepal2a46b902014-07-04 17:21:07 -07001998 private void abort(String callId) {
Ihab Awad60ac30b2014-05-20 22:32:12 -07001999 Log.d(this, "abort %s", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002000 findConnectionForAction(callId, "abort").onAbort();
Ihab Awad542e0ea2014-05-16 10:22:16 -07002001 }
2002
Tyler Gunnbe74de02014-08-29 14:51:48 -07002003 private void answerVideo(String callId, int videoState) {
2004 Log.d(this, "answerVideo %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302005 if (mConnectionById.containsKey(callId)) {
2006 findConnectionForAction(callId, "answer").onAnswer(videoState);
2007 } else {
2008 findConferenceForAction(callId, "answer").onAnswer(videoState);
2009 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002010 }
2011
Tyler Gunnbe74de02014-08-29 14:51:48 -07002012 private void answer(String callId) {
2013 Log.d(this, "answer %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302014 if (mConnectionById.containsKey(callId)) {
2015 findConnectionForAction(callId, "answer").onAnswer();
2016 } else {
2017 findConferenceForAction(callId, "answer").onAnswer();
2018 }
Tyler Gunnbe74de02014-08-29 14:51:48 -07002019 }
2020
Pooja Jaind34698d2017-12-28 14:15:31 +05302021 private void deflect(String callId, Uri address) {
2022 Log.d(this, "deflect %s", callId);
2023 findConnectionForAction(callId, "deflect").onDeflect(address);
2024 }
2025
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002026 private void reject(String callId) {
Ihab Awad60ac30b2014-05-20 22:32:12 -07002027 Log.d(this, "reject %s", callId);
Ravi Paluri80aa2142019-12-02 11:57:37 +05302028 if (mConnectionById.containsKey(callId)) {
2029 findConnectionForAction(callId, "reject").onReject();
2030 } else {
2031 findConferenceForAction(callId, "reject").onReject();
2032 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002033 }
2034
Bryce Lee81901682015-08-28 16:38:02 -07002035 private void reject(String callId, String rejectWithMessage) {
2036 Log.d(this, "reject %s with message", callId);
2037 findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
2038 }
2039
Tyler Gunnfacfdee2020-01-23 13:10:37 -08002040 private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
2041 Log.d(this, "reject %s with reason %d", callId, rejectReason);
2042 findConnectionForAction(callId, "reject").onReject(rejectReason);
2043 }
2044
Bryce Leecac50772015-11-17 15:13:29 -08002045 private void silence(String callId) {
2046 Log.d(this, "silence %s", callId);
2047 findConnectionForAction(callId, "silence").onSilence();
2048 }
2049
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002050 private void disconnect(String callId) {
Ihab Awad60ac30b2014-05-20 22:32:12 -07002051 Log.d(this, "disconnect %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002052 if (mConnectionById.containsKey(callId)) {
2053 findConnectionForAction(callId, "disconnect").onDisconnect();
2054 } else {
2055 findConferenceForAction(callId, "disconnect").onDisconnect();
2056 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002057 }
2058
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002059 private void hold(String callId) {
Ihab Awad60ac30b2014-05-20 22:32:12 -07002060 Log.d(this, "hold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002061 if (mConnectionById.containsKey(callId)) {
2062 findConnectionForAction(callId, "hold").onHold();
2063 } else {
2064 findConferenceForAction(callId, "hold").onHold();
2065 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002066 }
2067
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002068 private void unhold(String callId) {
Ihab Awad60ac30b2014-05-20 22:32:12 -07002069 Log.d(this, "unhold %s", callId);
Santos Cordon0159ac02014-08-21 14:28:11 -07002070 if (mConnectionById.containsKey(callId)) {
2071 findConnectionForAction(callId, "unhold").onUnhold();
2072 } else {
2073 findConferenceForAction(callId, "unhold").onUnhold();
2074 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002075 }
2076
Yorke Lee4af59352015-05-13 14:14:54 -07002077 private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
2078 Log.d(this, "onAudioStateChanged %s %s", callId, callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002079 if (mConnectionById.containsKey(callId)) {
Yorke Lee4af59352015-05-13 14:14:54 -07002080 findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2081 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002082 } else {
Yorke Lee4af59352015-05-13 14:14:54 -07002083 findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
2084 callAudioState);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002085 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002086 }
2087
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002088 private void playDtmfTone(String callId, char digit) {
2089 Log.d(this, "playDtmfTone %s %c", callId, digit);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002090 if (mConnectionById.containsKey(callId)) {
2091 findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2092 } else {
2093 findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
2094 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002095 }
2096
2097 private void stopDtmfTone(String callId) {
2098 Log.d(this, "stopDtmfTone %s", callId);
Yorke Leea0d3ca92014-09-15 19:18:13 -07002099 if (mConnectionById.containsKey(callId)) {
2100 findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
2101 } else {
2102 findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
2103 }
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002104 }
2105
Santos Cordon823fd3c2014-08-07 18:35:18 -07002106 private void conference(String callId1, String callId2) {
2107 Log.d(this, "conference %s, %s", callId1, callId2);
Santos Cordon980acb92014-05-31 10:31:19 -07002108
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002109 // Attempt to get second connection or conference.
Santos Cordon823fd3c2014-08-07 18:35:18 -07002110 Connection connection2 = findConnectionForAction(callId2, "conference");
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002111 Conference conference2 = getNullConference();
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002112 if (connection2 == getNullConnection()) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002113 conference2 = findConferenceForAction(callId2, "conference");
2114 if (conference2 == getNullConference()) {
2115 Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
2116 callId2);
2117 return;
2118 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07002119 }
Santos Cordonb6939982014-06-04 20:20:58 -07002120
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002121 // Attempt to get first connection or conference and perform merge.
Ihab Awad50e35062014-09-30 09:17:03 -07002122 Connection connection1 = findConnectionForAction(callId1, "conference");
2123 if (connection1 == getNullConnection()) {
2124 Conference conference1 = findConferenceForAction(callId1, "addConnection");
2125 if (conference1 == getNullConference()) {
2126 Log.w(this,
2127 "Connection1 or Conference1 missing in conference request %s.",
2128 callId1);
2129 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002130 // Call 1 is a conference.
2131 if (connection2 != getNullConnection()) {
2132 // Call 2 is a connection so merge via call 1 (conference).
2133 conference1.onMerge(connection2);
2134 } else {
2135 // Call 2 is ALSO a conference; this should never happen.
2136 Log.wtf(this, "There can only be one conference and an attempt was made to " +
2137 "merge two conferences.");
2138 return;
2139 }
Ihab Awad50e35062014-09-30 09:17:03 -07002140 }
2141 } else {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08002142 // Call 1 is a connection.
2143 if (conference2 != getNullConference()) {
2144 // Call 2 is a conference, so merge via call 2.
2145 conference2.onMerge(connection1);
2146 } else {
2147 // Call 2 is a connection, so merge together.
2148 onConference(connection1, connection2);
2149 }
Ihab Awad50e35062014-09-30 09:17:03 -07002150 }
Santos Cordon980acb92014-05-31 10:31:19 -07002151 }
2152
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002153 private void splitFromConference(String callId) {
Santos Cordonb6939982014-06-04 20:20:58 -07002154 Log.d(this, "splitFromConference(%s)", callId);
Santos Cordon980acb92014-05-31 10:31:19 -07002155
2156 Connection connection = findConnectionForAction(callId, "splitFromConference");
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07002157 if (connection == getNullConnection()) {
Santos Cordon980acb92014-05-31 10:31:19 -07002158 Log.w(this, "Connection missing in conference request %s.", callId);
2159 return;
2160 }
2161
Santos Cordon0159ac02014-08-21 14:28:11 -07002162 Conference conference = connection.getConference();
2163 if (conference != null) {
2164 conference.onSeparate(connection);
2165 }
Santos Cordon980acb92014-05-31 10:31:19 -07002166 }
2167
Santos Cordona4868042014-09-04 17:39:22 -07002168 private void mergeConference(String callId) {
2169 Log.d(this, "mergeConference(%s)", callId);
2170 Conference conference = findConferenceForAction(callId, "mergeConference");
2171 if (conference != null) {
2172 conference.onMerge();
2173 }
2174 }
2175
2176 private void swapConference(String callId) {
2177 Log.d(this, "swapConference(%s)", callId);
2178 Conference conference = findConferenceForAction(callId, "swapConference");
2179 if (conference != null) {
2180 conference.onSwap();
2181 }
2182 }
2183
Ravi Paluri404babb2020-01-23 19:02:44 +05302184 private void addConferenceParticipants(String callId, List<Uri> participants) {
2185 Log.d(this, "addConferenceParticipants(%s)", callId);
2186 if (mConnectionById.containsKey(callId)) {
2187 findConnectionForAction(callId, "addConferenceParticipants")
2188 .onAddConferenceParticipants(participants);
2189 } else {
2190 findConferenceForAction(callId, "addConferenceParticipants")
2191 .onAddConferenceParticipants(participants);
2192 }
2193 }
2194
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002195 /**
2196 * Notifies a {@link Connection} of a request to pull an external call.
2197 *
2198 * See {@link Call#pullExternalCall()}.
2199 *
2200 * @param callId The ID of the call to pull.
2201 */
2202 private void pullExternalCall(String callId) {
2203 Log.d(this, "pullExternalCall(%s)", callId);
2204 Connection connection = findConnectionForAction(callId, "pullExternalCall");
2205 if (connection != null) {
2206 connection.onPullExternalCall();
2207 }
2208 }
2209
2210 /**
2211 * Notifies a {@link Connection} of a call event.
2212 *
2213 * See {@link Call#sendCallEvent(String, Bundle)}.
2214 *
2215 * @param callId The ID of the call receiving the event.
2216 * @param event The event.
2217 * @param extras Extras associated with the event.
2218 */
2219 private void sendCallEvent(String callId, String event, Bundle extras) {
2220 Log.d(this, "sendCallEvent(%s, %s)", callId, event);
2221 Connection connection = findConnectionForAction(callId, "sendCallEvent");
2222 if (connection != null) {
2223 connection.onCallEvent(event, extras);
2224 }
Tyler Gunn876dbfb2016-03-14 15:18:07 -07002225 }
2226
Tyler Gunndee56a82016-03-23 16:06:34 -07002227 /**
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002228 * Notifies a {@link Connection} that a handover has completed.
2229 *
2230 * @param callId The ID of the call which completed handover.
2231 */
2232 private void notifyHandoverComplete(String callId) {
2233 Log.d(this, "notifyHandoverComplete(%s)", callId);
2234 Connection connection = findConnectionForAction(callId, "notifyHandoverComplete");
2235 if (connection != null) {
2236 connection.onHandoverComplete();
2237 }
2238 }
2239
2240 /**
Tyler Gunndee56a82016-03-23 16:06:34 -07002241 * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
2242 * <p>
2243 * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
2244 * the {@link android.telecom.Call#putExtra(String, boolean)},
2245 * {@link android.telecom.Call#putExtra(String, int)},
2246 * {@link android.telecom.Call#putExtra(String, String)},
2247 * {@link Call#removeExtras(List)}.
2248 *
2249 * @param callId The ID of the call receiving the event.
2250 * @param extras The new extras bundle.
2251 */
2252 private void handleExtrasChanged(String callId, Bundle extras) {
2253 Log.d(this, "handleExtrasChanged(%s, %s)", callId, extras);
2254 if (mConnectionById.containsKey(callId)) {
2255 findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2256 } else if (mConferenceById.containsKey(callId)) {
2257 findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
2258 }
2259 }
2260
Hall Liub64ac4c2017-02-06 10:49:48 -08002261 private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
2262 Log.d(this, "startRtt(%s)", callId);
2263 if (mConnectionById.containsKey(callId)) {
2264 findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
2265 } else if (mConferenceById.containsKey(callId)) {
2266 Log.w(this, "startRtt called on a conference.");
2267 }
2268 }
2269
2270 private void stopRtt(String callId) {
2271 Log.d(this, "stopRtt(%s)", callId);
2272 if (mConnectionById.containsKey(callId)) {
2273 findConnectionForAction(callId, "stopRtt").onStopRtt();
2274 } else if (mConferenceById.containsKey(callId)) {
2275 Log.w(this, "stopRtt called on a conference.");
2276 }
2277 }
2278
2279 private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
2280 Log.d(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
2281 if (mConnectionById.containsKey(callId)) {
2282 findConnectionForAction(callId, "handleRttUpgradeResponse")
2283 .handleRttUpgradeResponse(rttTextStream);
2284 } else if (mConferenceById.containsKey(callId)) {
2285 Log.w(this, "handleRttUpgradeResponse called on a conference.");
2286 }
2287 }
2288
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002289 private void onPostDialContinue(String callId, boolean proceed) {
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002290 Log.d(this, "onPostDialContinue(%s)", callId);
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002291 findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
Evan Charlton6dea4ac2014-06-03 14:07:13 -07002292 }
2293
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002294 private void onAdapterAttached() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002295 if (mAreAccountsInitialized) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002296 // No need to query again if we already did it.
2297 return;
2298 }
2299
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002300 String callingPackage = getOpPackageName();
2301
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002302 mAdapter.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
Santos Cordon52d8a152014-06-17 19:08:45 -07002303 @Override
2304 public void onResult(
2305 final List<ComponentName> componentNames,
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002306 final List<IBinder> services) {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002307 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002308 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002309 public void loggedRun() {
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002310 for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
Santos Cordon52d8a152014-06-17 19:08:45 -07002311 mRemoteConnectionManager.addConnectionService(
2312 componentNames.get(i),
Sailesh Nepal2a46b902014-07-04 17:21:07 -07002313 IConnectionService.Stub.asInterface(services.get(i)));
Santos Cordon52d8a152014-06-17 19:08:45 -07002314 }
Ihab Awad5d0410f2014-07-30 10:07:40 -07002315 onAccountsInitialized();
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002316 Log.d(this, "remote connection services found: " + services);
Santos Cordon52d8a152014-06-17 19:08:45 -07002317 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002318 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002319 }
2320
2321 @Override
2322 public void onError() {
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002323 mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
Ihab Awad6107bab2014-08-18 09:23:25 -07002324 @Override
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002325 public void loggedRun() {
Ihab Awad9c3f1882014-06-30 21:17:13 -07002326 mAreAccountsInitialized = true;
Santos Cordon52d8a152014-06-17 19:08:45 -07002327 }
Brad Ebinger0c3541b2016-11-01 14:11:38 -07002328 }.prepare());
Santos Cordon52d8a152014-06-17 19:08:45 -07002329 }
Tyler Gunn4c69fb32019-05-17 10:49:16 -07002330 }, callingPackage);
Santos Cordon52d8a152014-06-17 19:08:45 -07002331 }
2332
Ihab Awadf8b69882014-07-25 15:14:01 -07002333 /**
2334 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002335 * incoming request. This is used by {@code ConnectionService}s that are registered with
2336 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
2337 * SIM-based incoming calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002338 *
2339 * @param connectionManagerPhoneAccount See description at
2340 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2341 * @param request Details about the incoming call.
2342 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2343 * not handle the call.
2344 */
2345 public final RemoteConnection createRemoteIncomingConnection(
2346 PhoneAccountHandle connectionManagerPhoneAccount,
2347 ConnectionRequest request) {
2348 return mRemoteConnectionManager.createRemoteConnection(
2349 connectionManagerPhoneAccount, request, true);
Santos Cordon52d8a152014-06-17 19:08:45 -07002350 }
2351
2352 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002353 * Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
Santos Cordona663f862014-10-29 13:49:58 -07002354 * outgoing request. This is used by {@code ConnectionService}s that are registered with
2355 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
2356 * SIM-based {@code ConnectionService} to place its outgoing calls.
Ihab Awadf8b69882014-07-25 15:14:01 -07002357 *
2358 * @param connectionManagerPhoneAccount See description at
2359 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Cuihtlauac ALVARADO0b3b2a52016-09-13 14:49:41 +02002360 * @param request Details about the outgoing call.
Ihab Awadf8b69882014-07-25 15:14:01 -07002361 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2362 * not handle the call.
2363 */
2364 public final RemoteConnection createRemoteOutgoingConnection(
2365 PhoneAccountHandle connectionManagerPhoneAccount,
2366 ConnectionRequest request) {
2367 return mRemoteConnectionManager.createRemoteConnection(
2368 connectionManagerPhoneAccount, request, false);
2369 }
2370
2371 /**
Santos Cordona663f862014-10-29 13:49:58 -07002372 * Indicates to the relevant {@code RemoteConnectionService} that the specified
2373 * {@link RemoteConnection}s should be merged into a conference call.
2374 * <p>
2375 * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
2376 * be invoked.
2377 *
2378 * @param remoteConnection1 The first of the remote connections to conference.
2379 * @param remoteConnection2 The second of the remote connections to conference.
Ihab Awadb8e85c72014-08-23 20:34:57 -07002380 */
2381 public final void conferenceRemoteConnections(
Santos Cordona663f862014-10-29 13:49:58 -07002382 RemoteConnection remoteConnection1,
2383 RemoteConnection remoteConnection2) {
2384 mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
Ihab Awadb8e85c72014-08-23 20:34:57 -07002385 }
2386
2387 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002388 * Adds a new conference call. When a conference call is created either as a result of an
2389 * explicit request via {@link #onConference} or otherwise, the connection service should supply
2390 * an instance of {@link Conference} by invoking this method. A conference call provided by this
2391 * method will persist until {@link Conference#destroy} is invoked on the conference instance.
2392 *
2393 * @param conference The new conference object.
2394 */
2395 public final void addConference(Conference conference) {
Rekha Kumar07366812015-03-24 16:42:31 -07002396 Log.d(this, "addConference: conference=%s", conference);
2397
Santos Cordon823fd3c2014-08-07 18:35:18 -07002398 String id = addConferenceInternal(conference);
2399 if (id != null) {
2400 List<String> connectionIds = new ArrayList<>(2);
2401 for (Connection connection : conference.getConnections()) {
2402 if (mIdByConnection.containsKey(connection)) {
2403 connectionIds.add(mIdByConnection.get(connection));
2404 }
2405 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002406 conference.setTelecomCallId(id);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002407 ParcelableConference parcelableConference = new ParcelableConference(
Nancy Chenea38cca2014-09-05 16:38:49 -07002408 conference.getPhoneAccountHandle(),
Santos Cordon823fd3c2014-08-07 18:35:18 -07002409 conference.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002410 conference.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002411 conference.getConnectionProperties(),
Tyler Gunncd5d33c2015-01-12 09:02:01 -08002412 connectionIds,
Rekha Kumar07366812015-03-24 16:42:31 -07002413 conference.getVideoProvider() == null ?
2414 null : conference.getVideoProvider().getInterface(),
2415 conference.getVideoState(),
Andrew Lee3e3e2f22015-04-16 13:48:43 -07002416 conference.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002417 conference.getConnectionStartElapsedRealtimeMillis(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002418 conference.getStatusHints(),
Tyler Gunnac60f952019-05-31 07:23:16 -07002419 conference.getExtras(),
2420 conference.getAddress(),
2421 conference.getAddressPresentation(),
2422 conference.getCallerDisplayName(),
2423 conference.getCallerDisplayNamePresentation());
Andrew Lee0f51da32015-04-16 13:11:55 -07002424
Santos Cordon823fd3c2014-08-07 18:35:18 -07002425 mAdapter.addConferenceCall(id, parcelableConference);
Rekha Kumar07366812015-03-24 16:42:31 -07002426 mAdapter.setVideoProvider(id, conference.getVideoProvider());
2427 mAdapter.setVideoState(id, conference.getVideoState());
Santos Cordon823fd3c2014-08-07 18:35:18 -07002428
2429 // Go through any child calls and set the parent.
2430 for (Connection connection : conference.getConnections()) {
2431 String connectionId = mIdByConnection.get(connection);
2432 if (connectionId != null) {
2433 mAdapter.setIsConferenced(connectionId, id);
2434 }
2435 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002436 onConferenceAdded(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002437 }
2438 }
2439
2440 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002441 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
2442 * connection.
2443 *
2444 * @param phoneAccountHandle The phone account handle for the connection.
2445 * @param connection The connection to add.
2446 */
2447 public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
2448 Connection connection) {
Tyler Gunn78da7812017-05-09 14:34:57 -07002449 addExistingConnection(phoneAccountHandle, connection, null /* conference */);
2450 }
2451
2452 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002453 * Call to inform Telecom that your {@link ConnectionService} has released call resources (e.g
2454 * microphone, camera).
2455 *
Pengquan Menge3bf7e22018-02-22 17:30:04 -08002456 * <p>
2457 * The {@link ConnectionService} will be disconnected when it failed to call this method within
2458 * 5 seconds after {@link #onConnectionServiceFocusLost()} is called.
2459 *
Pengquan Meng731c1a32017-11-21 18:01:13 -08002460 * @see ConnectionService#onConnectionServiceFocusLost()
2461 */
2462 public final void connectionServiceFocusReleased() {
2463 mAdapter.onConnectionServiceFocusReleased();
2464 }
2465
2466 /**
Tyler Gunn78da7812017-05-09 14:34:57 -07002467 * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
Tyler Gunn5567d742019-10-31 13:04:37 -07002468 * connection, as well as adding that connection to the specified conference.
2469 * <p>
2470 * Note: This API is intended ONLY for use by the Telephony stack to provide an easy way to add
2471 * IMS conference participants to be added to a conference in a single step; this helps ensure
2472 * UI updates happen atomically, rather than adding the connection and then adding it to
2473 * the conference in another step.
Tyler Gunn78da7812017-05-09 14:34:57 -07002474 *
2475 * @param phoneAccountHandle The phone account handle for the connection.
2476 * @param connection The connection to add.
2477 * @param conference The parent conference of the new connection.
2478 * @hide
2479 */
Tyler Gunn5567d742019-10-31 13:04:37 -07002480 @SystemApi
2481 public final void addExistingConnection(@NonNull PhoneAccountHandle phoneAccountHandle,
2482 @NonNull Connection connection, @NonNull Conference conference) {
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002483
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002484 String id = addExistingConnectionInternal(phoneAccountHandle, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002485 if (id != null) {
2486 List<String> emptyList = new ArrayList<>(0);
Tyler Gunn78da7812017-05-09 14:34:57 -07002487 String conferenceId = null;
2488 if (conference != null) {
2489 conferenceId = mIdByConference.get(conference);
2490 }
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002491
2492 ParcelableConnection parcelableConnection = new ParcelableConnection(
2493 phoneAccountHandle,
2494 connection.getState(),
Ihab Awad5c9c86e2014-11-12 13:41:16 -08002495 connection.getConnectionCapabilities(),
Tyler Gunn720c6642016-03-22 09:02:47 -07002496 connection.getConnectionProperties(),
Christine Hallstrom2830ce92016-11-30 16:06:42 -08002497 connection.getSupportedAudioRoutes(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002498 connection.getAddress(),
2499 connection.getAddressPresentation(),
2500 connection.getCallerDisplayName(),
2501 connection.getCallerDisplayNamePresentation(),
2502 connection.getVideoProvider() == null ?
2503 null : connection.getVideoProvider().getInterface(),
2504 connection.getVideoState(),
2505 connection.isRingbackRequested(),
2506 connection.getAudioModeIsVoip(),
Roshan Piuse927ec02015-07-15 15:47:21 -07002507 connection.getConnectTimeMillis(),
Tyler Gunnc9503d62020-01-27 10:30:51 -08002508 connection.getConnectionStartElapsedRealtimeMillis(),
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002509 connection.getStatusHints(),
2510 connection.getDisconnectCause(),
Santos Cordon6b7f9552015-05-27 17:21:45 -07002511 emptyList,
Tyler Gunn78da7812017-05-09 14:34:57 -07002512 connection.getExtras(),
Tyler Gunn6986a632019-06-25 13:45:32 -07002513 conferenceId,
Tyler Gunnd57d76c2019-09-24 14:53:23 -07002514 connection.getCallDirection(),
2515 Connection.VERIFICATION_STATUS_NOT_VERIFIED);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002516 mAdapter.addExistingConnection(id, parcelableConnection);
2517 }
2518 }
2519
2520 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002521 * Returns all the active {@code Connection}s for which this {@code ConnectionService}
2522 * has taken responsibility.
2523 *
2524 * @return A collection of {@code Connection}s created by this {@code ConnectionService}.
Santos Cordonb6939982014-06-04 20:20:58 -07002525 */
Sailesh Nepal091768c2014-06-30 15:15:23 -07002526 public final Collection<Connection> getAllConnections() {
Santos Cordonb6939982014-06-04 20:20:58 -07002527 return mConnectionById.values();
2528 }
2529
2530 /**
Santos Cordona6018b92016-02-16 14:23:12 -08002531 * Returns all the active {@code Conference}s for which this {@code ConnectionService}
2532 * has taken responsibility.
2533 *
2534 * @return A collection of {@code Conference}s created by this {@code ConnectionService}.
2535 */
2536 public final Collection<Conference> getAllConferences() {
2537 return mConferenceById.values();
2538 }
2539
2540 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002541 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2542 * incoming calls.
Evan Charltonbf11f982014-07-20 22:06:28 -07002543 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002544 * @param connectionManagerPhoneAccount See description at
2545 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2546 * @param request Details about the incoming call.
2547 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2548 * not handle the call.
Ihab Awad542e0ea2014-05-16 10:22:16 -07002549 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002550 public Connection onCreateIncomingConnection(
2551 PhoneAccountHandle connectionManagerPhoneAccount,
2552 ConnectionRequest request) {
2553 return null;
2554 }
Ravi Paluri80aa2142019-12-02 11:57:37 +05302555 /**
2556 * Create a {@code Connection} given an incoming request. This is used to attach to existing
2557 * incoming conference call.
2558 *
2559 * @param connectionManagerPhoneAccount See description at
2560 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2561 * @param request Details about the incoming call.
2562 * @return The {@code Connection} object to satisfy this call, or {@code null} to
2563 * not handle the call.
2564 */
2565 public @Nullable Conference onCreateIncomingConference(
2566 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2567 @Nullable ConnectionRequest request) {
2568 return null;
2569 }
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002570
2571 /**
Tyler Gunn041a1fe2017-05-12 10:04:49 -07002572 * Called after the {@link Connection} returned by
2573 * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
2574 * or {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} has been
2575 * added to the {@link ConnectionService} and sent to Telecom.
2576 *
2577 * @param connection the {@link Connection}.
2578 * @hide
2579 */
2580 public void onCreateConnectionComplete(Connection connection) {
2581 }
2582
2583 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302584 * Called after the {@link Conference} returned by
2585 * {@link #onCreateIncomingConference(PhoneAccountHandle, ConnectionRequest)}
2586 * or {@link #onCreateOutgoingConference(PhoneAccountHandle, ConnectionRequest)} has been
2587 * added to the {@link ConnectionService} and sent to Telecom.
2588 *
2589 * @param conference the {@link Conference}.
2590 * @hide
2591 */
2592 public void onCreateConferenceComplete(Conference conference) {
2593 }
2594
2595
2596 /**
Tyler Gunnf5035432017-01-09 09:43:12 -08002597 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2598 * incoming {@link Connection} was denied.
2599 * <p>
2600 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2601 * {@link Connection}, but Telecom has determined that the call cannot be allowed at this time.
2602 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2603 * {@link Connection}.
2604 * <p>
2605 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2606 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002607 * @param connectionManagerPhoneAccount See description at
2608 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002609 * @param request The incoming connection request.
2610 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002611 public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2612 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002613 }
2614
2615 /**
2616 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2617 * outgoing {@link Connection} was denied.
2618 * <p>
2619 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2620 * {@link Connection}, but Telecom has determined that the call cannot be placed at this time.
2621 * The {@link ConnectionService} is responisible for informing the user that the
2622 * {@link Connection} cannot be made at this time.
2623 * <p>
2624 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2625 *
Tyler Gunn159f35c2017-03-02 09:28:37 -08002626 * @param connectionManagerPhoneAccount See description at
2627 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
Tyler Gunnf5035432017-01-09 09:43:12 -08002628 * @param request The outgoing connection request.
2629 */
Tyler Gunn159f35c2017-03-02 09:28:37 -08002630 public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
2631 ConnectionRequest request) {
Tyler Gunnf5035432017-01-09 09:43:12 -08002632 }
2633
2634 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302635 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2636 * incoming {@link Conference} was denied.
2637 * <p>
2638 * Used when a self-managed {@link ConnectionService} attempts to create a new incoming
2639 * {@link Conference}, but Telecom has determined that the call cannot be allowed at this time.
2640 * The {@link ConnectionService} is responsible for silently rejecting the new incoming
2641 * {@link Conference}.
2642 * <p>
2643 * See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
2644 *
2645 * @param connectionManagerPhoneAccount See description at
2646 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2647 * @param request The incoming connection request.
2648 */
2649 public void onCreateIncomingConferenceFailed(
2650 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2651 @Nullable ConnectionRequest request) {
2652 }
2653
2654 /**
2655 * Called by Telecom to inform the {@link ConnectionService} that its request to create a new
2656 * outgoing {@link Conference} was denied.
2657 * <p>
2658 * Used when a self-managed {@link ConnectionService} attempts to create a new outgoing
2659 * {@link Conference}, but Telecom has determined that the call cannot be placed at this time.
2660 * The {@link ConnectionService} is responisible for informing the user that the
2661 * {@link Conference} cannot be made at this time.
2662 * <p>
2663 * See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
2664 *
2665 * @param connectionManagerPhoneAccount See description at
2666 * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
2667 * @param request The outgoing connection request.
2668 */
2669 public void onCreateOutgoingConferenceFailed(
2670 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2671 @Nullable ConnectionRequest request) {
2672 }
2673
2674
2675 /**
Shriram Ganesh6bf35ac2014-12-11 17:53:38 -08002676 * Trigger recalculate functinality for conference calls. This is used when a Telephony
2677 * Connection is part of a conference controller but is not yet added to Connection
2678 * Service and hence cannot be added to the conference call.
2679 *
2680 * @hide
2681 */
2682 public void triggerConferenceRecalculate() {
2683 }
2684
2685 /**
Ihab Awadf8b69882014-07-25 15:14:01 -07002686 * Create a {@code Connection} given an outgoing request. This is used to initiate new
2687 * outgoing calls.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002688 *
Ihab Awadf8b69882014-07-25 15:14:01 -07002689 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2690 * this call.
2691 * <p>
2692 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2693 * has registered one or more {@code PhoneAccount}s having
2694 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2695 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2696 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2697 * making the connection.
2698 * <p>
2699 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2700 * being asked to make a direct connection. The
2701 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2702 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2703 * making the connection.
2704 * @param request Details about the outgoing call.
2705 * @return The {@code Connection} object to satisfy this call, or the result of an invocation
Andrew Lee7f3d41f2014-09-11 17:33:16 -07002706 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
Sailesh Nepalc5b01572014-07-14 16:29:44 -07002707 */
Ihab Awadf8b69882014-07-25 15:14:01 -07002708 public Connection onCreateOutgoingConnection(
2709 PhoneAccountHandle connectionManagerPhoneAccount,
2710 ConnectionRequest request) {
2711 return null;
2712 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07002713
2714 /**
Ravi Paluri80aa2142019-12-02 11:57:37 +05302715 * Create a {@code Conference} given an outgoing request. This is used to initiate new
2716 * outgoing conference call.
2717 *
2718 * @param connectionManagerPhoneAccount The connection manager account to use for managing
2719 * this call.
2720 * <p>
2721 * If this parameter is not {@code null}, it means that this {@code ConnectionService}
2722 * has registered one or more {@code PhoneAccount}s having
2723 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. This parameter will contain
2724 * one of these {@code PhoneAccount}s, while the {@code request} will contain another
2725 * (usually but not always distinct) {@code PhoneAccount} to be used for actually
2726 * making the connection.
2727 * <p>
2728 * If this parameter is {@code null}, it means that this {@code ConnectionService} is
2729 * being asked to make a direct connection. The
2730 * {@link ConnectionRequest#getAccountHandle()} of parameter {@code request} will be
2731 * a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
2732 * making the connection.
2733 * @param request Details about the outgoing call.
2734 * @return The {@code Conference} object to satisfy this call, or the result of an invocation
2735 * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
2736 */
2737 public @Nullable Conference onCreateOutgoingConference(
2738 @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
2739 @Nullable ConnectionRequest request) {
2740 return null;
2741 }
2742
2743
2744 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08002745 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
2746 * outgoing handover {@link Connection}.
2747 * <p>
2748 * A call handover is the process where an ongoing call is transferred from one app (i.e.
2749 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
2750 * mobile network call in a video calling app. The mobile network call via the Telephony stack
2751 * is referred to as the source of the handover, and the video calling app is referred to as the
2752 * destination.
2753 * <p>
2754 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
2755 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
2756 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
2757 * device.
2758 * <p>
2759 * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
2760 * device when the user initiates a handover request from one app to another. The user request
2761 * originates in the {@link InCallService} via
2762 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
2763 * <p>
2764 * For a full discussion of the handover process and the APIs involved, see
2765 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
2766 * <p>
2767 * Implementations of this method should return an instance of {@link Connection} which
2768 * represents the handover. If your app does not wish to accept a handover to it at this time,
2769 * you can return {@code null}. The code below shows an example of how this is done.
2770 * <pre>
2771 * {@code
2772 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
2773 * fromPhoneAccountHandle, ConnectionRequest request) {
2774 * if (!isHandoverAvailable()) {
2775 * return null;
2776 * }
2777 * MyConnection connection = new MyConnection();
2778 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
2779 * connection.setVideoState(request.getVideoState());
2780 * return connection;
2781 * }
2782 * }
2783 * </pre>
2784 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07002785 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
2786 * ConnectionService which needs to handover the call.
Tyler Gunn9d127732018-03-02 15:45:51 -08002787 * @param request Details about the call to handover.
2788 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07002789 */
2790 public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
2791 ConnectionRequest request) {
2792 return null;
2793 }
2794
2795 /**
Tyler Gunn9d127732018-03-02 15:45:51 -08002796 * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
2797 * incoming handover {@link Connection}.
2798 * <p>
2799 * A call handover is the process where an ongoing call is transferred from one app (i.e.
2800 * {@link ConnectionService} to another app. The user could, for example, choose to continue a
2801 * mobile network call in a video calling app. The mobile network call via the Telephony stack
2802 * is referred to as the source of the handover, and the video calling app is referred to as the
2803 * destination.
2804 * <p>
2805 * When considering a handover scenario the <em>initiating</em> device is where a user initiated
2806 * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
2807 * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
2808 * device.
2809 * <p>
2810 * This method is called on the destination app on the <em>receiving</em> device when the
2811 * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
2812 * accept an incoming handover from the <em>initiating</em> device.
2813 * <p>
2814 * For a full discussion of the handover process and the APIs involved, see
2815 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
2816 * <p>
2817 * Implementations of this method should return an instance of {@link Connection} which
2818 * represents the handover. The code below shows an example of how this is done.
2819 * <pre>
2820 * {@code
2821 * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
2822 * fromPhoneAccountHandle, ConnectionRequest request) {
2823 * // Given that your app requested to accept the handover, you should not return null here.
2824 * MyConnection connection = new MyConnection();
2825 * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
2826 * connection.setVideoState(request.getVideoState());
2827 * return connection;
2828 * }
2829 * }
2830 * </pre>
2831 *
Sanket Padawea8eddd42017-11-03 11:07:35 -07002832 * @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
2833 * ConnectionService which needs to handover the call.
2834 * @param request Details about the call which needs to be handover.
Tyler Gunn9d127732018-03-02 15:45:51 -08002835 * @return {@link Connection} instance corresponding to the handover call.
Sanket Padawea8eddd42017-11-03 11:07:35 -07002836 */
2837 public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
2838 ConnectionRequest request) {
2839 return null;
2840 }
2841
2842 /**
2843 * Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
2844 * invocation which failed.
Tyler Gunn9d127732018-03-02 15:45:51 -08002845 * <p>
2846 * For a full discussion of the handover process and the APIs involved, see
2847 * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
2848 *
2849 * @param request Details about the call which failed to handover.
2850 * @param error Reason for handover failure. Will be one of the
Sanket Padawea8eddd42017-11-03 11:07:35 -07002851 */
Tyler Gunn9d127732018-03-02 15:45:51 -08002852 public void onHandoverFailed(ConnectionRequest request,
2853 @Call.Callback.HandoverFailureErrors int error) {
Sanket Padawea8eddd42017-11-03 11:07:35 -07002854 return;
2855 }
2856
2857 /**
Yorke Leec3cf9822014-10-02 09:38:39 -07002858 * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
2859 * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
2860 * call created using
2861 * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
2862 *
Yorke Lee770ed6e2014-10-06 18:58:52 -07002863 * @hide
Yorke Leec3cf9822014-10-02 09:38:39 -07002864 */
2865 public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
2866 ConnectionRequest request) {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07002867 return null;
Yorke Leec3cf9822014-10-02 09:38:39 -07002868 }
2869
2870 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002871 * Conference two specified connections. Invoked when the user has made a request to merge the
2872 * specified connections into a conference call. In response, the connection service should
2873 * create an instance of {@link Conference} and pass it into {@link #addConference}.
Santos Cordonb6939982014-06-04 20:20:58 -07002874 *
Santos Cordon823fd3c2014-08-07 18:35:18 -07002875 * @param connection1 A connection to merge into a conference call.
2876 * @param connection2 A connection to merge into a conference call.
Santos Cordonb6939982014-06-04 20:20:58 -07002877 */
Santos Cordon823fd3c2014-08-07 18:35:18 -07002878 public void onConference(Connection connection1, Connection connection2) {}
Santos Cordonb6939982014-06-04 20:20:58 -07002879
Santos Cordona663f862014-10-29 13:49:58 -07002880 /**
Pengquan Meng70c9885332017-10-02 18:09:03 -07002881 * Called when a connection is added.
2882 * @hide
2883 */
2884 public void onConnectionAdded(Connection connection) {}
2885
2886 /**
2887 * Called when a connection is removed.
2888 * @hide
2889 */
2890 public void onConnectionRemoved(Connection connection) {}
2891
2892 /**
2893 * Called when a conference is added.
2894 * @hide
2895 */
2896 public void onConferenceAdded(Conference conference) {}
2897
2898 /**
2899 * Called when a conference is removed.
2900 * @hide
2901 */
2902 public void onConferenceRemoved(Conference conference) {}
2903
2904 /**
Santos Cordona663f862014-10-29 13:49:58 -07002905 * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
2906 * When this method is invoked, this {@link ConnectionService} should create its own
2907 * representation of the conference call and send it to telecom using {@link #addConference}.
2908 * <p>
2909 * This is only relevant to {@link ConnectionService}s which are registered with
2910 * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
2911 *
2912 * @param conference The remote conference call.
2913 */
Ihab Awadb8e85c72014-08-23 20:34:57 -07002914 public void onRemoteConferenceAdded(RemoteConference conference) {}
2915
Santos Cordon823fd3c2014-08-07 18:35:18 -07002916 /**
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002917 * Called when an existing connection is added remotely.
2918 * @param connection The existing connection which was added.
2919 */
2920 public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
2921
2922 /**
Pengquan Meng731c1a32017-11-21 18:01:13 -08002923 * Called when the {@link ConnectionService} has lost the call focus.
2924 * The {@link ConnectionService} should release the call resources and invokes
2925 * {@link ConnectionService#connectionServiceFocusReleased()} to inform telecom that it has
2926 * released the call resources.
2927 */
2928 public void onConnectionServiceFocusLost() {}
2929
2930 /**
2931 * Called when the {@link ConnectionService} has gained the call focus. The
2932 * {@link ConnectionService} can acquire the call resources at this time.
2933 */
2934 public void onConnectionServiceFocusGained() {}
2935
2936 /**
Santos Cordon823fd3c2014-08-07 18:35:18 -07002937 * @hide
2938 */
2939 public boolean containsConference(Conference conference) {
2940 return mIdByConference.containsKey(conference);
2941 }
2942
Ihab Awadb8e85c72014-08-23 20:34:57 -07002943 /** {@hide} */
2944 void addRemoteConference(RemoteConference remoteConference) {
2945 onRemoteConferenceAdded(remoteConference);
2946 }
2947
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002948 /** {@hide} */
2949 void addRemoteExistingConnection(RemoteConnection remoteConnection) {
2950 onRemoteExistingConnectionAdded(remoteConnection);
2951 }
2952
Ihab Awad5d0410f2014-07-30 10:07:40 -07002953 private void onAccountsInitialized() {
2954 mAreAccountsInitialized = true;
2955 for (Runnable r : mPreInitializationConnectionRequests) {
2956 r.run();
2957 }
2958 mPreInitializationConnectionRequests.clear();
2959 }
2960
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002961 /**
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002962 * Adds an existing connection to the list of connections, identified by a new call ID unique
2963 * to this connection service.
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002964 *
2965 * @param connection The connection.
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002966 * @return The ID of the connection (e.g. the call-id).
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002967 */
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002968 private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
2969 String id;
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07002970
2971 if (connection.getExtras() != null && connection.getExtras()
2972 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
2973 id = connection.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
2974 Log.d(this, "addExistingConnectionInternal - conn %s reusing original id %s",
2975 connection.getTelecomCallId(), id);
2976 } else if (handle == null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002977 // If no phone account handle was provided, we cannot be sure the call ID is unique,
2978 // so just use a random UUID.
2979 id = UUID.randomUUID().toString();
2980 } else {
2981 // Phone account handle was provided, so use the ConnectionService class name as a
2982 // prefix for a unique incremental call ID.
2983 id = handle.getComponentName().getClassName() + "@" + getNextCallId();
2984 }
Pengquan Meng70c9885332017-10-02 18:09:03 -07002985 addConnection(handle, id, connection);
Tyler Gunn4a57b9b2014-10-30 14:27:48 -07002986 return id;
2987 }
2988
Pengquan Meng70c9885332017-10-02 18:09:03 -07002989 private void addConnection(PhoneAccountHandle handle, String callId, Connection connection) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07002990 connection.setTelecomCallId(callId);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002991 mConnectionById.put(callId, connection);
2992 mIdByConnection.put(connection, callId);
2993 connection.addConnectionListener(mConnectionListener);
Santos Cordon823fd3c2014-08-07 18:35:18 -07002994 connection.setConnectionService(this);
Pengquan Meng70c9885332017-10-02 18:09:03 -07002995 connection.setPhoneAccountHandle(handle);
2996 onConnectionAdded(connection);
Ihab Awad542e0ea2014-05-16 10:22:16 -07002997 }
2998
Anthony Lee30e65842014-11-06 16:30:53 -08002999 /** {@hide} */
3000 protected void removeConnection(Connection connection) {
Santos Cordon823fd3c2014-08-07 18:35:18 -07003001 connection.unsetConnectionService(this);
Ihab Awad542e0ea2014-05-16 10:22:16 -07003002 connection.removeConnectionListener(mConnectionListener);
Chenjie Luoe370b532016-05-12 16:59:43 -07003003 String id = mIdByConnection.get(connection);
3004 if (id != null) {
3005 mConnectionById.remove(id);
3006 mIdByConnection.remove(connection);
3007 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003008 onConnectionRemoved(connection);
Chenjie Luoe370b532016-05-12 16:59:43 -07003009 }
Ihab Awad542e0ea2014-05-16 10:22:16 -07003010 }
3011
Santos Cordon823fd3c2014-08-07 18:35:18 -07003012 private String addConferenceInternal(Conference conference) {
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003013 String originalId = null;
3014 if (conference.getExtras() != null && conference.getExtras()
3015 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
3016 originalId = conference.getExtras().getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
3017 Log.d(this, "addConferenceInternal: conf %s reusing original id %s",
3018 conference.getTelecomCallId(),
3019 originalId);
3020 }
Santos Cordon823fd3c2014-08-07 18:35:18 -07003021 if (mIdByConference.containsKey(conference)) {
3022 Log.w(this, "Re-adding an existing conference: %s.", conference);
3023 } else if (conference != null) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003024 // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
3025 // cannot determine a ConnectionService class name to associate with the ID, so use
3026 // a unique UUID (for now).
Tyler Gunncd6ccfd2016-10-17 15:48:19 -07003027 String id = originalId == null ? UUID.randomUUID().toString() : originalId;
Santos Cordon823fd3c2014-08-07 18:35:18 -07003028 mConferenceById.put(id, conference);
3029 mIdByConference.put(conference, id);
3030 conference.addListener(mConferenceListener);
3031 return id;
3032 }
3033
3034 return null;
3035 }
3036
3037 private void removeConference(Conference conference) {
3038 if (mIdByConference.containsKey(conference)) {
3039 conference.removeListener(mConferenceListener);
3040
3041 String id = mIdByConference.get(conference);
3042 mConferenceById.remove(id);
3043 mIdByConference.remove(conference);
3044 mAdapter.removeCall(id);
Pengquan Meng70c9885332017-10-02 18:09:03 -07003045
3046 onConferenceRemoved(conference);
Santos Cordon823fd3c2014-08-07 18:35:18 -07003047 }
3048 }
3049
Ihab Awad542e0ea2014-05-16 10:22:16 -07003050 private Connection findConnectionForAction(String callId, String action) {
Tyler Gunn0a88f2e2017-06-16 20:20:34 -07003051 if (callId != null && mConnectionById.containsKey(callId)) {
Ihab Awad542e0ea2014-05-16 10:22:16 -07003052 return mConnectionById.get(callId);
3053 }
Ihab Awad60ac30b2014-05-20 22:32:12 -07003054 Log.w(this, "%s - Cannot find Connection %s", action, callId);
Sailesh Nepalcf7020b2014-08-20 10:07:19 -07003055 return getNullConnection();
3056 }
3057
3058 static synchronized Connection getNullConnection() {
3059 if (sNullConnection == null) {
3060 sNullConnection = new Connection() {};
3061 }
3062 return sNullConnection;
Santos Cordon7c7bc7f2014-07-28 18:15:48 -07003063 }
Santos Cordon0159ac02014-08-21 14:28:11 -07003064
3065 private Conference findConferenceForAction(String conferenceId, String action) {
3066 if (mConferenceById.containsKey(conferenceId)) {
3067 return mConferenceById.get(conferenceId);
3068 }
3069 Log.w(this, "%s - Cannot find conference %s", action, conferenceId);
3070 return getNullConference();
3071 }
3072
Ihab Awadb8e85c72014-08-23 20:34:57 -07003073 private List<String> createConnectionIdList(List<Connection> connections) {
3074 List<String> ids = new ArrayList<>();
3075 for (Connection c : connections) {
3076 if (mIdByConnection.containsKey(c)) {
3077 ids.add(mIdByConnection.get(c));
3078 }
3079 }
3080 Collections.sort(ids);
3081 return ids;
3082 }
3083
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003084 /**
3085 * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003086 * {@link Conferenceable}s passed in.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003087 *
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003088 * @param conferenceables The {@link Conferenceable} connections and conferences.
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003089 * @return List of string conference and call Ids.
3090 */
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003091 private List<String> createIdList(List<Conferenceable> conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003092 List<String> ids = new ArrayList<>();
Tyler Gunndf2cbc82015-04-20 09:13:01 -07003093 for (Conferenceable c : conferenceables) {
Tyler Gunn6d76ca02014-11-17 15:49:51 -08003094 // Only allow Connection and Conference conferenceables.
3095 if (c instanceof Connection) {
3096 Connection connection = (Connection) c;
3097 if (mIdByConnection.containsKey(connection)) {
3098 ids.add(mIdByConnection.get(connection));
3099 }
3100 } else if (c instanceof Conference) {
3101 Conference conference = (Conference) c;
3102 if (mIdByConference.containsKey(conference)) {
3103 ids.add(mIdByConference.get(conference));
3104 }
3105 }
3106 }
3107 Collections.sort(ids);
3108 return ids;
3109 }
3110
Santos Cordon0159ac02014-08-21 14:28:11 -07003111 private Conference getNullConference() {
3112 if (sNullConference == null) {
3113 sNullConference = new Conference(null) {};
3114 }
3115 return sNullConference;
3116 }
Santos Cordon29f2f2e2014-09-11 19:50:24 -07003117
3118 private void endAllConnections() {
3119 // Unbound from telecomm. We should end all connections and conferences.
3120 for (Connection connection : mIdByConnection.keySet()) {
3121 // only operate on top-level calls. Conference calls will be removed on their own.
3122 if (connection.getConference() == null) {
3123 connection.onDisconnect();
3124 }
3125 }
3126 for (Conference conference : mIdByConference.keySet()) {
3127 conference.onDisconnect();
3128 }
3129 }
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003130
3131 /**
3132 * Retrieves the next call ID as maintainted by the connection service.
3133 *
3134 * @return The call ID.
3135 */
3136 private int getNextCallId() {
Brad Ebingerb32d4f82016-10-24 16:40:49 -07003137 synchronized (mIdSyncRoot) {
Tyler Gunnf0500bd2015-09-01 10:59:48 -07003138 return ++mId;
3139 }
3140 }
Brad Ebinger99f17ce2019-09-11 18:06:51 -07003141
3142 /**
3143 * Returns this handler, ONLY FOR TESTING.
3144 * @hide
3145 */
3146 @VisibleForTesting
3147 public Handler getHandler() {
3148 return mHandler;
3149 }
Santos Cordon980acb92014-05-31 10:31:19 -07003150}