blob: bb011bf7e10a21aa5e24e6be95aae8a2a4c8f8da [file] [log] [blame]
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001/*
2 * Copyright 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 Gunn7cc70b42014-09-12 22:17:27 -070017package com.android.server.telecom;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070018
Brad Ebinger91350952016-06-29 17:27:08 -070019import android.app.AppOpsManager;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070020import android.content.ComponentName;
Tyler Gunn91d43cf2014-09-17 12:19:39 -070021import android.content.Context;
Sailesh Nepale8ecb982014-07-11 17:19:42 -070022import android.net.Uri;
Ihab Awad512d6352015-03-26 13:43:22 -070023import android.os.Binder;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070024import android.os.Bundle;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070025import android.os.IBinder;
Hall Liuaeece4e2017-02-14 16:42:12 -080026import android.os.ParcelFileDescriptor;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070027import android.os.RemoteException;
Evan Charlton105d9772014-11-25 14:08:53 -080028import android.os.UserHandle;
Yorke Lee2a66f7b2015-05-13 14:21:19 -070029import android.telecom.CallAudioState;
Tyler Gunn7cc70b42014-09-12 22:17:27 -070030import android.telecom.Connection;
31import android.telecom.ConnectionRequest;
32import android.telecom.ConnectionService;
Andrew Lee701dc002014-09-11 21:29:12 -070033import android.telecom.DisconnectCause;
Tyler Gunn7cc70b42014-09-12 22:17:27 -070034import android.telecom.GatewayInfo;
Brad Ebinger953e1af2016-10-05 15:45:22 -070035import android.telecom.Log;
Brad Ebingerb78b0232016-10-24 16:40:33 -070036import android.telecom.Logging.Session;
Tyler Gunn7cc70b42014-09-12 22:17:27 -070037import android.telecom.ParcelableConference;
38import android.telecom.ParcelableConnection;
Tyler Gunn7cc70b42014-09-12 22:17:27 -070039import android.telecom.PhoneAccountHandle;
40import android.telecom.StatusHints;
41import android.telecom.TelecomManager;
42import android.telecom.VideoProfile;
Srikanth Chintala1c586c62017-05-04 20:55:01 +053043import android.telephony.TelephonyManager;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070044
Hall Liuf62630a2015-10-27 14:53:39 -070045import com.android.internal.annotations.VisibleForTesting;
Tyler Gunn7cc70b42014-09-12 22:17:27 -070046import com.android.internal.telecom.IConnectionService;
47import com.android.internal.telecom.IConnectionServiceAdapter;
48import com.android.internal.telecom.IVideoProvider;
49import com.android.internal.telecom.RemoteServiceCallback;
Tyler Gunn91d43cf2014-09-17 12:19:39 -070050import com.android.internal.util.Preconditions;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070051
Sailesh Nepalc92c4362014-07-04 18:33:21 -070052import java.util.ArrayList;
Ihab Awadb78b2762014-07-25 15:16:23 -070053import java.util.Collections;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070054import java.util.HashMap;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070055import java.util.List;
56import java.util.Map;
57import java.util.Set;
Jay Shraunera82c8f72014-08-14 15:49:16 -070058import java.util.concurrent.ConcurrentHashMap;
Sailesh Nepalc92c4362014-07-04 18:33:21 -070059
60/**
61 * Wrapper for {@link IConnectionService}s, handles binding to {@link IConnectionService} and keeps
62 * track of when the object can safely be unbound. Other classes should not use
63 * {@link IConnectionService} directly and instead should use this class to invoke methods of
64 * {@link IConnectionService}.
65 */
Hall Liuf62630a2015-10-27 14:53:39 -070066@VisibleForTesting
Pengquan Mengd7f92cf2017-11-21 17:52:42 -080067public class ConnectionServiceWrapper extends ServiceBinder implements
68 ConnectionServiceFocusManager.ConnectionServiceFocus {
Sailesh Nepalc92c4362014-07-04 18:33:21 -070069
70 private final class Adapter extends IConnectionServiceAdapter.Stub {
Ihab Awad6fb37c82014-08-07 19:48:57 -070071
Sailesh Nepalc92c4362014-07-04 18:33:21 -070072 @Override
Brad Ebinger11623a32015-11-25 13:52:02 -080073 public void handleCreateConnectionComplete(String callId, ConnectionRequest request,
Brad Ebinger65912752016-10-28 12:32:06 -070074 ParcelableConnection connection, Session.Info sessionInfo) {
75 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_HANDLE_CREATE_CONNECTION_COMPLETE);
Ihab Awad512d6352015-03-26 13:43:22 -070076 long token = Binder.clearCallingIdentity();
77 try {
78 synchronized (mLock) {
79 logIncoming("handleCreateConnectionComplete %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -070080 ConnectionServiceWrapper.this
81 .handleCreateConnectionComplete(callId, request, connection);
Tyler Gunnddb03e12017-05-12 11:54:41 -070082
83 if (mServiceInterface != null) {
84 logOutgoing("createConnectionComplete %s", callId);
85 try {
86 mServiceInterface.createConnectionComplete(callId,
87 Log.getExternalSession());
88 } catch (RemoteException e) {
89 }
90 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -070091 }
Ihab Awad512d6352015-03-26 13:43:22 -070092 } finally {
93 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -080094 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -070095 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -070096 }
97
Sailesh Nepalc92c4362014-07-04 18:33:21 -070098 @Override
Brad Ebinger65912752016-10-28 12:32:06 -070099 public void setActive(String callId, Session.Info sessionInfo) {
100 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_ACTIVE);
Ihab Awad512d6352015-03-26 13:43:22 -0700101 long token = Binder.clearCallingIdentity();
102 try {
103 synchronized (mLock) {
104 logIncoming("setActive %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700105 Call call = mCallIdMapper.getCall(callId);
106 if (call != null) {
107 mCallsManager.markCallAsActive(call);
108 } else {
109 // Log.w(this, "setActive, unknown call id: %s", msg.obj);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700110 }
111 }
Ihab Awad512d6352015-03-26 13:43:22 -0700112 } finally {
113 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800114 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700115 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700116 }
117
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700118 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700119 public void setRinging(String callId, Session.Info sessionInfo) {
120 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_RINGING);
Ihab Awad512d6352015-03-26 13:43:22 -0700121 long token = Binder.clearCallingIdentity();
122 try {
123 synchronized (mLock) {
124 logIncoming("setRinging %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700125 Call call = mCallIdMapper.getCall(callId);
126 if (call != null) {
127 mCallsManager.markCallAsRinging(call);
128 } else {
129 // Log.w(this, "setRinging, unknown call id: %s", msg.obj);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700130 }
131 }
Ihab Awad512d6352015-03-26 13:43:22 -0700132 } finally {
133 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800134 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700135 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700136 }
137
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700138 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700139 public void setVideoProvider(String callId, IVideoProvider videoProvider,
140 Session.Info sessionInfo) {
141 Log.startSession(sessionInfo, "CSW.sVP");
Ihab Awad512d6352015-03-26 13:43:22 -0700142 long token = Binder.clearCallingIdentity();
143 try {
144 synchronized (mLock) {
145 logIncoming("setVideoProvider %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700146 Call call = mCallIdMapper.getCall(callId);
147 if (call != null) {
148 call.setVideoProvider(videoProvider);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700149 }
150 }
Ihab Awad512d6352015-03-26 13:43:22 -0700151 } finally {
152 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800153 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700154 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700155 }
156
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700157 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700158 public void setDialing(String callId, Session.Info sessionInfo) {
159 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_DIALING);
Ihab Awad512d6352015-03-26 13:43:22 -0700160 long token = Binder.clearCallingIdentity();
161 try {
162 synchronized (mLock) {
163 logIncoming("setDialing %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700164 Call call = mCallIdMapper.getCall(callId);
165 if (call != null) {
166 mCallsManager.markCallAsDialing(call);
167 } else {
168 // Log.w(this, "setDialing, unknown call id: %s", msg.obj);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700169 }
170 }
Ihab Awad512d6352015-03-26 13:43:22 -0700171 } finally {
172 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800173 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700174 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700175 }
176
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700177 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700178 public void setPulling(String callId, Session.Info sessionInfo) {
179 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_PULLING);
Tyler Gunn1e37be52016-07-11 08:54:23 -0700180 long token = Binder.clearCallingIdentity();
181 try {
182 synchronized (mLock) {
183 logIncoming("setPulling %s", callId);
184 Call call = mCallIdMapper.getCall(callId);
185 if (call != null) {
186 mCallsManager.markCallAsPulling(call);
187 }
188 }
189 } finally {
190 Binder.restoreCallingIdentity(token);
191 Log.endSession();
192 }
193 }
194
195 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700196 public void setDisconnected(String callId, DisconnectCause disconnectCause,
197 Session.Info sessionInfo) {
198 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_DISCONNECTED);
Ihab Awad512d6352015-03-26 13:43:22 -0700199 long token = Binder.clearCallingIdentity();
200 try {
201 synchronized (mLock) {
202 logIncoming("setDisconnected %s %s", callId, disconnectCause);
Tyler Gunn8452be02015-09-17 09:57:02 -0700203 Call call = mCallIdMapper.getCall(callId);
204 Log.d(this, "disconnect call %s %s", disconnectCause, call);
205 if (call != null) {
206 mCallsManager.markCallAsDisconnected(call, disconnectCause);
207 } else {
208 // Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700209 }
210 }
Ihab Awad512d6352015-03-26 13:43:22 -0700211 } finally {
212 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800213 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700214 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700215 }
216
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700217 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700218 public void setOnHold(String callId, Session.Info sessionInfo) {
219 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_ON_HOLD);
Ihab Awad512d6352015-03-26 13:43:22 -0700220 long token = Binder.clearCallingIdentity();
221 try {
222 synchronized (mLock) {
223 logIncoming("setOnHold %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700224 Call call = mCallIdMapper.getCall(callId);
225 if (call != null) {
226 mCallsManager.markCallAsOnHold(call);
227 } else {
228 // Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700229 }
230 }
Ihab Awad512d6352015-03-26 13:43:22 -0700231 } finally {
232 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800233 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700234 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700235 }
236
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700237 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700238 public void setRingbackRequested(String callId, boolean ringback,
239 Session.Info sessionInfo) {
240 Log.startSession(sessionInfo, "CSW.SRR");
Ihab Awad512d6352015-03-26 13:43:22 -0700241 long token = Binder.clearCallingIdentity();
242 try {
243 synchronized (mLock) {
244 logIncoming("setRingbackRequested %s %b", callId, ringback);
Tyler Gunn8452be02015-09-17 09:57:02 -0700245 Call call = mCallIdMapper.getCall(callId);
246 if (call != null) {
247 call.setRingbackRequested(ringback);
248 } else {
249 // Log.w(this, "setRingback, unknown call id: %s", args.arg1);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700250 }
251 }
Ihab Awad512d6352015-03-26 13:43:22 -0700252 } finally {
253 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800254 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700255 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700256 }
257
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700258 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700259 public void removeCall(String callId, Session.Info sessionInfo) {
260 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_REMOVE_CALL);
Ihab Awad512d6352015-03-26 13:43:22 -0700261 long token = Binder.clearCallingIdentity();
262 try {
263 synchronized (mLock) {
264 logIncoming("removeCall %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700265 Call call = mCallIdMapper.getCall(callId);
266 if (call != null) {
267 if (call.isAlive()) {
268 mCallsManager.markCallAsDisconnected(
269 call, new DisconnectCause(DisconnectCause.REMOTE));
270 } else {
271 mCallsManager.markCallAsRemoved(call);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700272 }
273 }
274 }
Ihab Awad512d6352015-03-26 13:43:22 -0700275 } finally {
276 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800277 Log.endSession();
Ihab Awada02bef52014-08-13 18:18:42 -0700278 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700279 }
280
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700281 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700282 public void setConnectionCapabilities(String callId, int connectionCapabilities,
283 Session.Info sessionInfo) {
284 Log.startSession(sessionInfo, "CSW.sCC");
Ihab Awad512d6352015-03-26 13:43:22 -0700285 long token = Binder.clearCallingIdentity();
286 try {
287 synchronized (mLock) {
288 logIncoming("setConnectionCapabilities %s %d", callId, connectionCapabilities);
Tyler Gunn8452be02015-09-17 09:57:02 -0700289 Call call = mCallIdMapper.getCall(callId);
290 if (call != null) {
291 call.setConnectionCapabilities(connectionCapabilities);
292 } else {
293 // Log.w(ConnectionServiceWrapper.this,
294 // "setConnectionCapabilities, unknown call id: %s", msg.obj);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700295 }
296 }
Ihab Awad512d6352015-03-26 13:43:22 -0700297 } finally {
298 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800299 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700300 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700301 }
302
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700303 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700304 public void setConnectionProperties(String callId, int connectionProperties,
305 Session.Info sessionInfo) {
Tyler Gunn571d5e62016-03-15 15:55:18 -0700306 Log.startSession("CSW.sCP");
307 long token = Binder.clearCallingIdentity();
308 try {
309 synchronized (mLock) {
310 logIncoming("setConnectionProperties %s %d", callId, connectionProperties);
311 Call call = mCallIdMapper.getCall(callId);
312 if (call != null) {
313 call.setConnectionProperties(connectionProperties);
314 }
315 }
316 } finally {
317 Binder.restoreCallingIdentity(token);
318 Log.endSession();
319 }
320 }
321
322 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700323 public void setIsConferenced(String callId, String conferenceCallId,
324 Session.Info sessionInfo) {
325 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_IS_CONFERENCED);
Ihab Awad512d6352015-03-26 13:43:22 -0700326 long token = Binder.clearCallingIdentity();
327 try {
328 synchronized (mLock) {
329 logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
330 Call childCall = mCallIdMapper.getCall(callId);
331 if (childCall != null) {
332 if (conferenceCallId == null) {
333 Log.d(this, "unsetting parent: %s", conferenceCallId);
Tyler Gunn76581712017-05-09 14:39:42 -0700334 childCall.setParentAndChildCall(null);
Ihab Awad512d6352015-03-26 13:43:22 -0700335 } else {
336 Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
Tyler Gunn76581712017-05-09 14:39:42 -0700337 childCall.setParentAndChildCall(conferenceCall);
Ihab Awad512d6352015-03-26 13:43:22 -0700338 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700339 } else {
Ihab Awad512d6352015-03-26 13:43:22 -0700340 // Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700341 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700342 }
Ihab Awad512d6352015-03-26 13:43:22 -0700343 } finally {
344 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800345 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700346 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700347 }
348
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700349 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700350 public void setConferenceMergeFailed(String callId, Session.Info sessionInfo) {
351 Log.startSession(sessionInfo, "CSW.sCMF");
Anthony Leece75aa12015-04-24 15:36:26 -0700352 long token = Binder.clearCallingIdentity();
353 try {
354 synchronized (mLock) {
355 logIncoming("setConferenceMergeFailed %s", callId);
Tyler Gunn8452be02015-09-17 09:57:02 -0700356 // TODO: we should move the UI for indication a merge failure here
357 // from CallNotifier.onSuppServiceFailed(). This way the InCallUI can
358 // deliver the message anyway that they want. b/20530631.
359 Call call = mCallIdMapper.getCall(callId);
360 if (call != null) {
Brad Ebinger0d402552016-05-27 16:02:53 -0700361 call.onConnectionEvent(Connection.EVENT_CALL_MERGE_FAILED, null);
Tyler Gunn8452be02015-09-17 09:57:02 -0700362 } else {
363 Log.w(this, "setConferenceMergeFailed, unknown call id: %s", callId);
Anthony Leece75aa12015-04-24 15:36:26 -0700364 }
Anthony Leece75aa12015-04-24 15:36:26 -0700365 }
366 } finally {
367 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800368 Log.endSession();
Anthony Leece75aa12015-04-24 15:36:26 -0700369 }
370 }
371
372 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700373 public void addConferenceCall(String callId, ParcelableConference parcelableConference,
374 Session.Info sessionInfo) {
375 Log.startSession(sessionInfo, LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL);
Ihab Awad512d6352015-03-26 13:43:22 -0700376 long token = Binder.clearCallingIdentity();
377 try {
378 synchronized (mLock) {
379 if (mCallIdMapper.getCall(callId) != null) {
380 Log.w(this, "Attempting to add a conference call using an existing " +
381 "call id %s", callId);
382 return;
383 }
Tyler Gunn9b618b82016-10-17 15:54:35 -0700384 logIncoming("addConferenceCall %s %s [%s]", callId, parcelableConference,
385 parcelableConference.getConnectionIds());
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700386
Ihab Awad512d6352015-03-26 13:43:22 -0700387 // Make sure that there's at least one valid call. For remote connections
388 // we'll get a add conference msg from both the remote connection service
389 // and from the real connection service.
390 boolean hasValidCalls = false;
391 for (String connId : parcelableConference.getConnectionIds()) {
392 if (mCallIdMapper.getCall(connId) != null) {
393 hasValidCalls = true;
394 }
395 }
396 // But don't bail out if the connection count is 0, because that is a valid
397 // IMS conference state.
398 if (!hasValidCalls && parcelableConference.getConnectionIds().size() > 0) {
399 Log.d(this, "Attempting to add a conference with no valid calls");
400 return;
401 }
402
Ihab Awad512d6352015-03-26 13:43:22 -0700403 PhoneAccountHandle phAcc = null;
404 if (parcelableConference != null &&
405 parcelableConference.getPhoneAccount() != null) {
406 phAcc = parcelableConference.getPhoneAccount();
407 }
Tyler Gunn9b618b82016-10-17 15:54:35 -0700408
409 Bundle connectionExtras = parcelableConference.getExtras();
410
411 String connectIdToCheck = null;
412 if (connectionExtras != null && connectionExtras
413 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
414 // Conference was added via a connection manager, see if its original id is
415 // known.
416 connectIdToCheck = connectionExtras
417 .getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
418 } else {
419 connectIdToCheck = callId;
420 }
421
422 Call conferenceCall;
423 // Check to see if this conference has already been added.
424 Call alreadyAddedConnection = mCallsManager
425 .getAlreadyAddedConnection(connectIdToCheck);
426 if (alreadyAddedConnection != null && mCallIdMapper.getCall(callId) == null) {
427 // We are currently attempting to add the conference via a connection mgr,
428 // and the originating ConnectionService has already added it. Instead of
429 // making a new Telecom call, we will simply add it to the ID mapper here,
430 // and replace the ConnectionService on the call.
431 mCallIdMapper.addCall(alreadyAddedConnection, callId);
432 alreadyAddedConnection.replaceConnectionService(
433 ConnectionServiceWrapper.this);
434 conferenceCall = alreadyAddedConnection;
435 } else {
436 // need to create a new Call
437 Call newConferenceCall = mCallsManager.createConferenceCall(callId,
438 phAcc, parcelableConference);
439 mCallIdMapper.addCall(newConferenceCall, callId);
440 newConferenceCall.setConnectionService(ConnectionServiceWrapper.this);
441 conferenceCall = newConferenceCall;
442 }
Ihab Awad512d6352015-03-26 13:43:22 -0700443
444 Log.d(this, "adding children to conference %s phAcc %s",
445 parcelableConference.getConnectionIds(), phAcc);
446 for (String connId : parcelableConference.getConnectionIds()) {
447 Call childCall = mCallIdMapper.getCall(connId);
448 Log.d(this, "found child: %s", connId);
449 if (childCall != null) {
Tyler Gunn76581712017-05-09 14:39:42 -0700450 childCall.setParentAndChildCall(conferenceCall);
Ihab Awad512d6352015-03-26 13:43:22 -0700451 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700452 }
453 }
Ihab Awad512d6352015-03-26 13:43:22 -0700454 } finally {
455 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800456 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700457 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700458 }
459
460 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700461 public void onPostDialWait(String callId, String remaining,
462 Session.Info sessionInfo) throws RemoteException {
463 Log.startSession(sessionInfo, "CSW.oPDW");
Ihab Awad512d6352015-03-26 13:43:22 -0700464 long token = Binder.clearCallingIdentity();
465 try {
466 synchronized (mLock) {
467 logIncoming("onPostDialWait %s %s", callId, remaining);
Tyler Gunn8452be02015-09-17 09:57:02 -0700468 Call call = mCallIdMapper.getCall(callId);
469 if (call != null) {
470 call.onPostDialWait(remaining);
471 } else {
472 // Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700473 }
474 }
Ihab Awad512d6352015-03-26 13:43:22 -0700475 } finally {
476 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800477 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700478 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700479 }
480
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700481 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700482 public void onPostDialChar(String callId, char nextChar,
483 Session.Info sessionInfo) throws RemoteException {
484 Log.startSession(sessionInfo, "CSW.oPDC");
Ihab Awad512d6352015-03-26 13:43:22 -0700485 long token = Binder.clearCallingIdentity();
486 try {
487 synchronized (mLock) {
488 logIncoming("onPostDialChar %s %s", callId, nextChar);
Tyler Gunn8452be02015-09-17 09:57:02 -0700489 Call call = mCallIdMapper.getCall(callId);
490 if (call != null) {
491 call.onPostDialChar(nextChar);
492 } else {
493 // Log.w(this, "onPostDialChar, unknown call id: %s", args.arg1);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700494 }
495 }
Ihab Awad512d6352015-03-26 13:43:22 -0700496 } finally {
497 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800498 Log.endSession();
Nancy Chena469f762014-12-09 18:29:20 -0800499 }
500 }
501
502 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700503 public void queryRemoteConnectionServices(RemoteServiceCallback callback,
504 Session.Info sessionInfo) {
Tony Mak240656f2015-12-04 11:36:22 +0000505 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
Brad Ebinger65912752016-10-28 12:32:06 -0700506 Log.startSession(sessionInfo, "CSW.qRCS");
Ihab Awad512d6352015-03-26 13:43:22 -0700507 long token = Binder.clearCallingIdentity();
508 try {
509 synchronized (mLock) {
510 logIncoming("queryRemoteConnectionServices %s", callback);
Tony Mak240656f2015-12-04 11:36:22 +0000511 ConnectionServiceWrapper.this
512 .queryRemoteConnectionServices(callingUserHandle, callback);
Ihab Awad512d6352015-03-26 13:43:22 -0700513 }
514 } finally {
515 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800516 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700517 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700518 }
519
520 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700521 public void setVideoState(String callId, int videoState, Session.Info sessionInfo) {
522 Log.startSession(sessionInfo, "CSW.sVS");
Ihab Awad512d6352015-03-26 13:43:22 -0700523 long token = Binder.clearCallingIdentity();
524 try {
525 synchronized (mLock) {
526 logIncoming("setVideoState %s %d", callId, videoState);
Tyler Gunn8452be02015-09-17 09:57:02 -0700527 Call call = mCallIdMapper.getCall(callId);
528 if (call != null) {
529 call.setVideoState(videoState);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700530 }
531 }
Ihab Awad512d6352015-03-26 13:43:22 -0700532 } finally {
533 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800534 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700535 }
Tyler Gunn0a388fc2014-07-17 12:21:17 -0700536 }
537
538 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700539 public void setIsVoipAudioMode(String callId, boolean isVoip, Session.Info sessionInfo) {
540 Log.startSession(sessionInfo, "CSW.sIVAM");
Ihab Awad512d6352015-03-26 13:43:22 -0700541 long token = Binder.clearCallingIdentity();
542 try {
543 synchronized (mLock) {
544 logIncoming("setIsVoipAudioMode %s %b", callId, isVoip);
Tyler Gunn8452be02015-09-17 09:57:02 -0700545 Call call = mCallIdMapper.getCall(callId);
546 if (call != null) {
547 call.setIsVoipAudioMode(isVoip);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700548 }
549 }
Ihab Awad512d6352015-03-26 13:43:22 -0700550 } finally {
551 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800552 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700553 }
Sailesh Nepal7e669572014-07-08 21:29:12 -0700554 }
Sailesh Nepal35faf8c2014-07-08 22:02:34 -0700555
556 @Override
Hall Liu9086fb12017-11-07 18:01:53 -0800557 public void setAudioRoute(String callId, int audioRoute,
558 String bluetoothAddress, Session.Info sessionInfo) {
Tyler Gunnacb3bc82017-01-09 09:43:56 -0800559 Log.startSession(sessionInfo, "CSW.sAR");
560 long token = Binder.clearCallingIdentity();
561 try {
562 synchronized (mLock) {
563 logIncoming("setAudioRoute %s %s", callId,
564 CallAudioState.audioRouteToString(audioRoute));
Hall Liu9086fb12017-11-07 18:01:53 -0800565 mCallsManager.setAudioRoute(audioRoute, bluetoothAddress);
Tyler Gunnacb3bc82017-01-09 09:43:56 -0800566 }
567 } finally {
568 Binder.restoreCallingIdentity(token);
569 Log.endSession();
570 }
571 }
572
573 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700574 public void setStatusHints(String callId, StatusHints statusHints,
575 Session.Info sessionInfo) {
576 Log.startSession(sessionInfo, "CSW.sSH");
Ihab Awad512d6352015-03-26 13:43:22 -0700577 long token = Binder.clearCallingIdentity();
578 try {
579 synchronized (mLock) {
580 logIncoming("setStatusHints %s %s", callId, statusHints);
Tyler Gunn8452be02015-09-17 09:57:02 -0700581 Call call = mCallIdMapper.getCall(callId);
582 if (call != null) {
583 call.setStatusHints(statusHints);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700584 }
585 }
Ihab Awad512d6352015-03-26 13:43:22 -0700586 } finally {
587 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800588 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700589 }
Sailesh Nepal35faf8c2014-07-08 22:02:34 -0700590 }
Sailesh Nepale8ecb982014-07-11 17:19:42 -0700591
592 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700593 public void putExtras(String callId, Bundle extras, Session.Info sessionInfo) {
594 Log.startSession(sessionInfo, "CSW.pE");
Santos Cordonb3907b32015-05-27 17:39:59 -0700595 long token = Binder.clearCallingIdentity();
596 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800597 synchronized (mLock) {
Jeff Sharkeye2e4cdf2016-03-18 12:19:02 -0600598 Bundle.setDefusable(extras, true);
Tyler Gunn8452be02015-09-17 09:57:02 -0700599 Call call = mCallIdMapper.getCall(callId);
600 if (call != null) {
Tyler Gunn961694a2016-03-21 16:01:40 -0700601 call.putExtras(Call.SOURCE_CONNECTION_SERVICE, extras);
602 }
603 }
604 } finally {
605 Binder.restoreCallingIdentity(token);
606 Log.endSession();
607 }
608 }
609
610 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700611 public void removeExtras(String callId, List<String> keys, Session.Info sessionInfo) {
612 Log.startSession(sessionInfo, "CSW.rE");
Tyler Gunn961694a2016-03-21 16:01:40 -0700613 long token = Binder.clearCallingIdentity();
614 try {
615 synchronized (mLock) {
616 logIncoming("removeExtra %s %s", callId, keys);
617 Call call = mCallIdMapper.getCall(callId);
618 if (call != null) {
619 call.removeExtras(Call.SOURCE_CONNECTION_SERVICE, keys);
Santos Cordonb3907b32015-05-27 17:39:59 -0700620 }
621 }
622 } finally {
623 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800624 Log.endSession();
Santos Cordonb3907b32015-05-27 17:39:59 -0700625 }
626 }
627
628 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700629 public void setAddress(String callId, Uri address, int presentation,
630 Session.Info sessionInfo) {
631 Log.startSession(sessionInfo, "CSW.sA");
Ihab Awad512d6352015-03-26 13:43:22 -0700632 long token = Binder.clearCallingIdentity();
633 try {
634 synchronized (mLock) {
635 logIncoming("setAddress %s %s %d", callId, address, presentation);
Tyler Gunn8452be02015-09-17 09:57:02 -0700636 Call call = mCallIdMapper.getCall(callId);
637 if (call != null) {
638 call.setHandle(address, presentation);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700639 }
640 }
Ihab Awad512d6352015-03-26 13:43:22 -0700641 } finally {
642 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800643 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700644 }
Sailesh Nepale8ecb982014-07-11 17:19:42 -0700645 }
646
647 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700648 public void setCallerDisplayName(String callId, String callerDisplayName, int presentation,
649 Session.Info sessionInfo) {
650 Log.startSession(sessionInfo, "CSW.sCDN");
Ihab Awad512d6352015-03-26 13:43:22 -0700651 long token = Binder.clearCallingIdentity();
652 try {
653 synchronized (mLock) {
654 logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName,
655 presentation);
Tyler Gunn8452be02015-09-17 09:57:02 -0700656 Call call = mCallIdMapper.getCall(callId);
657 if (call != null) {
658 call.setCallerDisplayName(callerDisplayName, presentation);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700659 }
660 }
Ihab Awad512d6352015-03-26 13:43:22 -0700661 } finally {
662 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800663 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700664 }
Sailesh Nepale8ecb982014-07-11 17:19:42 -0700665 }
Sailesh Nepal9d58de52014-07-18 14:53:19 -0700666
667 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700668 public void setConferenceableConnections(String callId, List<String> conferenceableCallIds,
669 Session.Info sessionInfo) {
670 Log.startSession(sessionInfo, "CSW.sCC");
Ihab Awad512d6352015-03-26 13:43:22 -0700671 long token = Binder.clearCallingIdentity();
672 try {
673 synchronized (mLock) {
Tyler Gunn9b618b82016-10-17 15:54:35 -0700674
Tyler Gunn8452be02015-09-17 09:57:02 -0700675 Call call = mCallIdMapper.getCall(callId);
676 if (call != null) {
Tyler Gunn9b618b82016-10-17 15:54:35 -0700677 logIncoming("setConferenceableConnections %s %s", callId,
678 conferenceableCallIds);
Tyler Gunn8452be02015-09-17 09:57:02 -0700679 List<Call> conferenceableCalls =
680 new ArrayList<>(conferenceableCallIds.size());
681 for (String otherId : conferenceableCallIds) {
682 Call otherCall = mCallIdMapper.getCall(otherId);
683 if (otherCall != null && otherCall != call) {
684 conferenceableCalls.add(otherCall);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700685 }
686 }
Tyler Gunn8452be02015-09-17 09:57:02 -0700687 call.setConferenceableCalls(conferenceableCalls);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700688 }
689 }
Ihab Awad512d6352015-03-26 13:43:22 -0700690 } finally {
691 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800692 Log.endSession();
Jay Shrauner969755a2014-08-11 20:34:43 -0700693 }
Santos Cordon12d61822014-07-29 16:02:20 -0700694 }
Tyler Gunn6e2b94e2014-10-30 11:05:22 -0700695
696 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700697 public void addExistingConnection(String callId, ParcelableConnection connection,
698 Session.Info sessionInfo) {
699 Log.startSession(sessionInfo, "CSW.aEC");
Brad Ebinger91350952016-06-29 17:27:08 -0700700 UserHandle userHandle = Binder.getCallingUserHandle();
701 // Check that the Calling Package matches PhoneAccountHandle's Component Package
702 PhoneAccountHandle callingPhoneAccountHandle = connection.getPhoneAccount();
703 if (callingPhoneAccountHandle != null) {
704 mAppOpsManager.checkPackage(Binder.getCallingUid(),
705 callingPhoneAccountHandle.getComponentName().getPackageName());
706 }
Ihab Awad512d6352015-03-26 13:43:22 -0700707 long token = Binder.clearCallingIdentity();
708 try {
709 synchronized (mLock) {
Brad Ebinger91350952016-06-29 17:27:08 -0700710 // Make sure that the PhoneAccount associated with the incoming
711 // ParcelableConnection is in fact registered to Telecom and is being called
712 // from the correct user.
713 List<PhoneAccountHandle> accountHandles =
714 mPhoneAccountRegistrar.getCallCapablePhoneAccounts(null /*uriScheme*/,
715 false /*includeDisabledAccounts*/, userHandle);
716 PhoneAccountHandle phoneAccountHandle = null;
717 for (PhoneAccountHandle accountHandle : accountHandles) {
718 if(accountHandle.equals(callingPhoneAccountHandle)) {
719 phoneAccountHandle = accountHandle;
720 }
721 }
Tyler Gunn9b618b82016-10-17 15:54:35 -0700722 // Allow the Sim call manager account as well, even if its disabled.
723 if (phoneAccountHandle == null && callingPhoneAccountHandle != null) {
724 if (callingPhoneAccountHandle.equals(
725 mPhoneAccountRegistrar.getSimCallManager(userHandle))) {
726 phoneAccountHandle = callingPhoneAccountHandle;
727 }
728 }
Brad Ebinger91350952016-06-29 17:27:08 -0700729 if (phoneAccountHandle != null) {
Tyler Gunn9b618b82016-10-17 15:54:35 -0700730 logIncoming("addExistingConnection %s %s", callId, connection);
731
732 Bundle connectionExtras = connection.getExtras();
733 String connectIdToCheck = null;
734 if (connectionExtras != null && connectionExtras
735 .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
736 connectIdToCheck = connectionExtras
737 .getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
738 } else {
739 connectIdToCheck = callId;
740 }
741 // Check to see if this Connection has already been added.
742 Call alreadyAddedConnection = mCallsManager
743 .getAlreadyAddedConnection(connectIdToCheck);
744
745 if (alreadyAddedConnection != null
746 && mCallIdMapper.getCall(callId) == null) {
747 mCallIdMapper.addCall(alreadyAddedConnection, callId);
748 alreadyAddedConnection
749 .replaceConnectionService(ConnectionServiceWrapper.this);
750 return;
751 }
752
Brad Ebinger91350952016-06-29 17:27:08 -0700753 Call existingCall = mCallsManager
754 .createCallForExistingConnection(callId, connection);
755 mCallIdMapper.addCall(existingCall, callId);
756 existingCall.setConnectionService(ConnectionServiceWrapper.this);
757 } else {
758 Log.e(this, new RemoteException("The PhoneAccount being used is not " +
759 "currently registered with Telecom."), "Unable to " +
760 "addExistingConnection.");
761 }
Ihab Awad512d6352015-03-26 13:43:22 -0700762 }
763 } finally {
764 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800765 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700766 }
Tyler Gunn6e2b94e2014-10-30 11:05:22 -0700767 }
Tyler Gunndb821912016-02-16 14:35:25 -0800768
769 @Override
Brad Ebinger65912752016-10-28 12:32:06 -0700770 public void onConnectionEvent(String callId, String event, Bundle extras,
771 Session.Info sessionInfo) {
772 Log.startSession(sessionInfo, "CSW.oCE");
Tyler Gunndb821912016-02-16 14:35:25 -0800773 long token = Binder.clearCallingIdentity();
774 try {
775 synchronized (mLock) {
Jeff Sharkeye2e4cdf2016-03-18 12:19:02 -0600776 Bundle.setDefusable(extras, true);
Tyler Gunndb821912016-02-16 14:35:25 -0800777 Call call = mCallIdMapper.getCall(callId);
778 if (call != null) {
Tyler Gunnd45e6d92016-03-10 20:15:39 -0800779 call.onConnectionEvent(event, extras);
Tyler Gunndb821912016-02-16 14:35:25 -0800780 }
781 }
782 } finally {
783 Binder.restoreCallingIdentity(token);
784 Log.endSession();
785 }
786 }
Hall Liuaeece4e2017-02-14 16:42:12 -0800787
788 @Override
789 public void onRttInitiationSuccess(String callId, Session.Info sessionInfo)
790 throws RemoteException {
791
792 }
793
794 @Override
795 public void onRttInitiationFailure(String callId, int reason, Session.Info sessionInfo)
796 throws RemoteException {
797 Log.startSession(sessionInfo, "CSW.oRIF");
798 long token = Binder.clearCallingIdentity();
799 try {
800 synchronized (mLock) {
801 Call call = mCallIdMapper.getCall(callId);
802 if (call != null) {
803 call.onRttConnectionFailure(reason);
804 }
805 }
806 } finally {
807 Binder.restoreCallingIdentity(token);
808 Log.endSession();
809 }
810 }
811
812 @Override
813 public void onRttSessionRemotelyTerminated(String callId, Session.Info sessionInfo)
814 throws RemoteException {
815
816 }
817
818 @Override
819 public void onRemoteRttRequest(String callId, Session.Info sessionInfo)
820 throws RemoteException {
821 Log.startSession(sessionInfo, "CSW.oRRR");
822 long token = Binder.clearCallingIdentity();
823 try {
824 synchronized (mLock) {
825 Call call = mCallIdMapper.getCall(callId);
826 if (call != null) {
827 call.onRemoteRttRequest();
828 }
829 }
830 } finally {
831 Binder.restoreCallingIdentity(token);
832 Log.endSession();
833 }
834 }
Srikanth Chintala1c586c62017-05-04 20:55:01 +0530835
836 @Override
837 public void onPhoneAccountChanged(String callId, PhoneAccountHandle pHandle,
838 Session.Info sessionInfo) throws RemoteException {
Brad Ebinger702f8f52017-08-18 13:09:06 -0700839 // Check that the Calling Package matches PhoneAccountHandle's Component Package
840 if (pHandle != null) {
841 mAppOpsManager.checkPackage(Binder.getCallingUid(),
842 pHandle.getComponentName().getPackageName());
843 }
Srikanth Chintala1c586c62017-05-04 20:55:01 +0530844 Log.startSession(sessionInfo, "CSW.oPAC");
845 long token = Binder.clearCallingIdentity();
846 try {
847 synchronized (mLock) {
848 Call call = mCallIdMapper.getCall(callId);
849 if (call != null) {
850 call.setTargetPhoneAccount(pHandle);
851 }
852 }
853 } finally {
854 Binder.restoreCallingIdentity(token);
855 Log.endSession();
856 }
857 }
Pengquan Meng4845c9b2017-12-01 12:03:28 -0800858
859 @Override
860 public void onConnectionServiceFocusReleased(Session.Info sessionInfo)
861 throws RemoteException {
Pengquan Meng4832f202017-12-20 16:13:04 -0800862 Log.startSession(sessionInfo, "CSW.oCSFR");
863 long token = Binder.clearCallingIdentity();
864 try {
865 synchronized (mLock) {
866 mConnSvrFocusListener.onConnectionServiceReleased(
867 ConnectionServiceWrapper.this);
868 }
869 } finally {
870 Binder.restoreCallingIdentity(token);
871 Log.endSession();
872 }
Pengquan Meng4845c9b2017-12-01 12:03:28 -0800873 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700874 }
875
876 private final Adapter mAdapter = new Adapter();
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700877 private final CallIdMapper mCallIdMapper = new CallIdMapper(Call::getConnectionId);
Sailesh Nepal664837f2014-07-14 16:31:51 -0700878 private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700879
Ihab Awad512d6352015-03-26 13:43:22 -0700880 private Binder2 mBinder = new Binder2();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700881 private IConnectionService mServiceInterface;
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700882 private final ConnectionServiceRepository mConnectionServiceRepository;
Tyler Gunn91d43cf2014-09-17 12:19:39 -0700883 private final PhoneAccountRegistrar mPhoneAccountRegistrar;
Ihab Awad8de76912015-02-17 12:25:52 -0800884 private final CallsManager mCallsManager;
Brad Ebinger91350952016-06-29 17:27:08 -0700885 private final AppOpsManager mAppOpsManager;
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700886
Pengquan Mengd7f92cf2017-11-21 17:52:42 -0800887 private ConnectionServiceFocusManager.ConnectionServiceFocusListener mConnSvrFocusListener;
888
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700889 /**
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700890 * Creates a connection service.
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700891 *
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700892 * @param componentName The component name of the service with which to bind.
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700893 * @param connectionServiceRepository Connection service repository.
Ihab Awadb78b2762014-07-25 15:16:23 -0700894 * @param phoneAccountRegistrar Phone account registrar
Ihab Awad8de76912015-02-17 12:25:52 -0800895 * @param callsManager Calls manager
Tyler Gunn91d43cf2014-09-17 12:19:39 -0700896 * @param context The context.
Evan Charlton105d9772014-11-25 14:08:53 -0800897 * @param userHandle The {@link UserHandle} to use when binding.
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700898 */
899 ConnectionServiceWrapper(
Ihab Awadb78b2762014-07-25 15:16:23 -0700900 ComponentName componentName,
901 ConnectionServiceRepository connectionServiceRepository,
Tyler Gunn91d43cf2014-09-17 12:19:39 -0700902 PhoneAccountRegistrar phoneAccountRegistrar,
Ihab Awad8de76912015-02-17 12:25:52 -0800903 CallsManager callsManager,
Evan Charlton105d9772014-11-25 14:08:53 -0800904 Context context,
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700905 TelecomSystem.SyncRoot lock,
Evan Charlton105d9772014-11-25 14:08:53 -0800906 UserHandle userHandle) {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700907 super(ConnectionService.SERVICE_INTERFACE, componentName, context, lock, userHandle);
Sailesh Nepal905dfba2014-07-14 08:20:41 -0700908 mConnectionServiceRepository = connectionServiceRepository;
Ihab Awadb78b2762014-07-25 15:16:23 -0700909 phoneAccountRegistrar.addListener(new PhoneAccountRegistrar.Listener() {
910 // TODO -- Upon changes to PhoneAccountRegistrar, need to re-wire connections
911 // To do this, we must proxy remote ConnectionService objects
912 });
Tyler Gunn91d43cf2014-09-17 12:19:39 -0700913 mPhoneAccountRegistrar = phoneAccountRegistrar;
Ihab Awad8de76912015-02-17 12:25:52 -0800914 mCallsManager = callsManager;
Brad Ebinger91350952016-06-29 17:27:08 -0700915 mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700916 }
917
918 /** See {@link IConnectionService#addConnectionServiceAdapter}. */
919 private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
920 if (isServiceValid("addConnectionServiceAdapter")) {
921 try {
Sailesh Nepal3fe8b722014-07-08 10:07:26 -0700922 logOutgoing("addConnectionServiceAdapter %s", adapter);
Brad Ebingerb78b0232016-10-24 16:40:33 -0700923 mServiceInterface.addConnectionServiceAdapter(adapter, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700924 } catch (RemoteException e) {
925 }
926 }
927 }
928
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700929 /** See {@link IConnectionService#removeConnectionServiceAdapter}. */
930 private void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
931 if (isServiceValid("removeConnectionServiceAdapter")) {
932 try {
933 logOutgoing("removeConnectionServiceAdapter %s", adapter);
Brad Ebingerb78b0232016-10-24 16:40:33 -0700934 mServiceInterface.removeConnectionServiceAdapter(adapter, Log.getExternalSession());
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700935 } catch (RemoteException e) {
936 }
937 }
938 }
939
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700940 /**
Sailesh Nepal664837f2014-07-14 16:31:51 -0700941 * Creates a new connection for a new outgoing call or to attach to an existing incoming call.
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700942 */
Brad Ebingerf1900072015-11-12 17:25:06 -0800943 @VisibleForTesting
944 public void createConnection(final Call call, final CreateConnectionResponse response) {
Sailesh Nepal664837f2014-07-14 16:31:51 -0700945 Log.d(this, "createConnection(%s) via %s.", call, getComponentName());
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700946 BindCallback callback = new BindCallback() {
947 @Override
948 public void onSuccess() {
949 String callId = mCallIdMapper.getCallId(call);
Sailesh Nepal664837f2014-07-14 16:31:51 -0700950 mPendingResponses.put(callId, response);
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700951
952 GatewayInfo gatewayInfo = call.getGatewayInfo();
Santos Cordonb3907b32015-05-27 17:39:59 -0700953 Bundle extras = call.getIntentExtras();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700954 if (gatewayInfo != null && gatewayInfo.getGatewayProviderPackageName() != null &&
Nancy Chen201b4372014-09-08 14:18:24 -0700955 gatewayInfo.getOriginalAddress() != null) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700956 extras = (Bundle) extras.clone();
957 extras.putString(
Tyler Gunn7cc70b42014-09-12 22:17:27 -0700958 TelecomManager.GATEWAY_PROVIDER_PACKAGE,
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700959 gatewayInfo.getGatewayProviderPackageName());
960 extras.putParcelable(
Tyler Gunn7cc70b42014-09-12 22:17:27 -0700961 TelecomManager.GATEWAY_ORIGINAL_ADDRESS,
Nancy Chen201b4372014-09-08 14:18:24 -0700962 gatewayInfo.getOriginalAddress());
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700963 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700964
mike dooley66f26d12016-12-19 13:25:47 -0800965 if (call.isIncoming() && mCallsManager.getEmergencyCallHelper()
966 .getLastEmergencyCallTimeMillis() > 0) {
mike dooleya2b067e2017-02-13 19:41:10 -0800967 // Add the last emergency call time to the connection request for incoming calls
968 if (extras == call.getIntentExtras()) {
969 extras = (Bundle) extras.clone();
970 }
mike dooley66f26d12016-12-19 13:25:47 -0800971 extras.putLong(android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS,
972 mCallsManager.getEmergencyCallHelper().getLastEmergencyCallTimeMillis());
mike dooley66f26d12016-12-19 13:25:47 -0800973 }
974
Tyler Gunn6f6f1c52017-04-17 18:22:04 -0700975 // Call is incoming and added because we're handing over from another; tell CS
976 // that its expected to handover.
Tyler Gunn141ef582017-05-26 13:38:13 -0700977 if (call.isIncoming() && call.getHandoverSourceCall() != null) {
Tyler Gunn6f6f1c52017-04-17 18:22:04 -0700978 extras.putBoolean(TelecomManager.EXTRA_IS_HANDOVER, true);
Tyler Gunn141ef582017-05-26 13:38:13 -0700979 extras.putParcelable(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT,
980 call.getHandoverSourceCall().getTargetPhoneAccount());
Tyler Gunn6f6f1c52017-04-17 18:22:04 -0700981 }
982
Hall Liuaeece4e2017-02-14 16:42:12 -0800983 Log.addEvent(call, LogUtils.Events.START_CONNECTION,
984 Log.piiHandle(call.getHandle()));
Tyler Gunna90ba732017-01-26 07:24:08 -0800985
Hall Liudd68bc32017-01-25 17:14:23 -0800986 ConnectionRequest connectionRequest = new ConnectionRequest.Builder()
987 .setAccountHandle(call.getTargetPhoneAccount())
988 .setAddress(call.getHandle())
Brad Ebinger6b0b6032017-02-23 17:03:01 -0800989 .setExtras(extras)
Hall Liudd68bc32017-01-25 17:14:23 -0800990 .setVideoState(call.getVideoState())
991 .setTelecomCallId(callId)
Tyler Gunn2b17f232017-03-08 08:51:00 -0800992 // For self-managed incoming calls, if there is another ongoing call Telecom
993 // is responsible for showing a UI to ask the user if they'd like to answer
994 // this new incoming call.
995 .setShouldShowIncomingCallUi(
996 !mCallsManager.shouldShowSystemIncomingCallUi(call))
Hall Liudd68bc32017-01-25 17:14:23 -0800997 .setRttPipeFromInCall(call.getInCallToCsRttPipeForCs())
998 .setRttPipeToInCall(call.getCsToInCallRttPipeForCs())
999 .build();
1000
1001 try {
Ihab Awadb78b2762014-07-25 15:16:23 -07001002 mServiceInterface.createConnection(
1003 call.getConnectionManagerPhoneAccount(),
Ihab Awad6fb37c82014-08-07 19:48:57 -07001004 callId,
Hall Liudd68bc32017-01-25 17:14:23 -08001005 connectionRequest,
Hall Liu32587202015-11-18 11:10:08 -08001006 call.shouldAttachToExistingConnection(),
Brad Ebingerb78b0232016-10-24 16:40:33 -07001007 call.isUnknown(),
1008 Log.getExternalSession());
Tyler Gunna90ba732017-01-26 07:24:08 -08001009
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001010 } catch (RemoteException e) {
Sailesh Nepal664837f2014-07-14 16:31:51 -07001011 Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
Ihab Awadfb5560d2014-08-18 09:32:51 -07001012 mPendingResponses.remove(callId).handleCreateConnectionFailure(
Andrew Lee701dc002014-09-11 21:29:12 -07001013 new DisconnectCause(DisconnectCause.ERROR, e.toString()));
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001014 }
1015 }
1016
1017 @Override
1018 public void onFailure() {
Sailesh Nepal905dfba2014-07-14 08:20:41 -07001019 Log.e(this, new Exception(), "Failure to call %s", getComponentName());
Andrew Lee701dc002014-09-11 21:29:12 -07001020 response.handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.ERROR));
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001021 }
1022 };
1023
Santos Cordon165c1ce2015-07-10 16:07:59 -07001024 mBinder.bind(callback, call);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001025 }
1026
Tyler Gunna90ba732017-01-26 07:24:08 -08001027 /**
1028 * Notifies the {@link ConnectionService} associated with a {@link Call} that the request to
1029 * create a connection has been denied or failed.
1030 * @param call The call.
1031 */
1032 void createConnectionFailed(final Call call) {
1033 Log.d(this, "createConnectionFailed(%s) via %s.", call, getComponentName());
1034 BindCallback callback = new BindCallback() {
1035 @Override
1036 public void onSuccess() {
1037 final String callId = mCallIdMapper.getCallId(call);
1038 // If still bound, tell the connection service create connection has failed.
1039 if (callId != null && isServiceValid("createConnectionFailed")) {
1040 Log.addEvent(call, LogUtils.Events.CREATE_CONNECTION_FAILED,
1041 Log.piiHandle(call.getHandle()));
1042 try {
1043 logOutgoing("createConnectionFailed %s", callId);
Tyler Gunn115c06e2017-03-02 09:29:07 -08001044 mServiceInterface.createConnectionFailed(
1045 call.getConnectionManagerPhoneAccount(),
1046 callId,
Tyler Gunna90ba732017-01-26 07:24:08 -08001047 new ConnectionRequest(
1048 call.getTargetPhoneAccount(),
1049 call.getHandle(),
1050 call.getIntentExtras(),
1051 call.getVideoState(),
1052 callId,
1053 false),
1054 call.isIncoming(),
1055 Log.getExternalSession());
1056 call.setDisconnectCause(new DisconnectCause(DisconnectCause.CANCELED));
1057 call.disconnect();
1058 } catch (RemoteException e) {
1059 }
1060 }
1061 }
1062
1063 @Override
1064 public void onFailure() {
1065 // Binding failed. Oh no.
1066 Log.w(this, "onFailure - could not bind to CS for call %s", call.getId());
1067 }
1068 };
1069
1070 mBinder.bind(callback, call);
1071 }
1072
Sanket Padawe29411c92017-11-30 16:51:08 -08001073 void handoverFailed(final Call call, final int reason) {
1074 Log.d(this, "handoverFailed(%s) via %s.", call, getComponentName());
1075 BindCallback callback = new BindCallback() {
1076 @Override
1077 public void onSuccess() {
1078 final String callId = mCallIdMapper.getCallId(call);
1079 // If still bound, tell the connection service create connection has failed.
1080 if (callId != null && isServiceValid("handoverFailed")) {
1081 Log.addEvent(call, LogUtils.Events.HANDOVER_FAILED,
1082 Log.piiHandle(call.getHandle()));
1083 try {
1084 mServiceInterface.handoverFailed(
1085 callId,
1086 new ConnectionRequest(
1087 call.getTargetPhoneAccount(),
1088 call.getHandle(),
1089 call.getIntentExtras(),
1090 call.getVideoState(),
1091 callId,
1092 false), reason, Log.getExternalSession());
1093 } catch (RemoteException e) {
1094 }
1095 }
1096 }
1097
1098 @Override
1099 public void onFailure() {
1100 // Binding failed.
1101 Log.w(this, "onFailure - could not bind to CS for call %s",
1102 call.getId());
1103 }
1104 };
1105
1106 mBinder.bind(callback, call);
1107 }
1108
Tyler Gunn7c031f22018-01-18 15:00:41 -08001109 void handoverComplete(final Call call) {
1110 Log.d(this, "handoverComplete(%s) via %s.", call, getComponentName());
1111 BindCallback callback = new BindCallback() {
1112 @Override
1113 public void onSuccess() {
1114 final String callId = mCallIdMapper.getCallId(call);
1115 // If still bound, tell the connection service create connection has failed.
1116 if (callId != null && isServiceValid("handoverComplete")) {
1117 try {
1118 mServiceInterface.handoverComplete(
1119 callId,
1120 Log.getExternalSession());
1121 } catch (RemoteException e) {
1122 }
1123 }
1124 }
1125
1126 @Override
1127 public void onFailure() {
1128 // Binding failed.
1129 Log.w(this, "onFailure - could not bind to CS for call %s",
1130 call.getId());
1131 }
1132 };
1133
1134 mBinder.bind(callback, call);
1135 }
1136
Brad Ebingerb78b0232016-10-24 16:40:33 -07001137 /** @see IConnectionService#abort(String, Session.Info) */
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001138 void abort(Call call) {
1139 // Clear out any pending outgoing call data
Jay Shrauner969755a2014-08-11 20:34:43 -07001140 final String callId = mCallIdMapper.getCallId(call);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001141
1142 // If still bound, tell the connection service to abort.
Jay Shrauner969755a2014-08-11 20:34:43 -07001143 if (callId != null && isServiceValid("abort")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001144 try {
1145 logOutgoing("abort %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001146 mServiceInterface.abort(callId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001147 } catch (RemoteException e) {
1148 }
1149 }
1150
Andrew Lee701dc002014-09-11 21:29:12 -07001151 removeCall(call, new DisconnectCause(DisconnectCause.LOCAL));
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001152 }
1153
Brad Ebingerb78b0232016-10-24 16:40:33 -07001154 /** @see IConnectionService#silence(String, Session.Info) */
Bryce Lee6d962522015-11-30 10:28:37 -08001155 void silence(Call call) {
1156 final String callId = mCallIdMapper.getCallId(call);
1157 if (callId != null && isServiceValid("silence")) {
1158 try {
1159 logOutgoing("silence %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001160 mServiceInterface.silence(callId, Log.getExternalSession());
Bryce Lee6d962522015-11-30 10:28:37 -08001161 } catch (RemoteException e) {
1162 }
1163 }
1164 }
1165
Brad Ebingerb78b0232016-10-24 16:40:33 -07001166 /** @see IConnectionService#hold(String, Session.Info) */
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001167 void hold(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001168 final String callId = mCallIdMapper.getCallId(call);
1169 if (callId != null && isServiceValid("hold")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001170 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001171 logOutgoing("hold %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001172 mServiceInterface.hold(callId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001173 } catch (RemoteException e) {
1174 }
1175 }
1176 }
1177
Brad Ebingerb78b0232016-10-24 16:40:33 -07001178 /** @see IConnectionService#unhold(String, Session.Info) */
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001179 void unhold(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001180 final String callId = mCallIdMapper.getCallId(call);
1181 if (callId != null && isServiceValid("unhold")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001182 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001183 logOutgoing("unhold %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001184 mServiceInterface.unhold(callId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001185 } catch (RemoteException e) {
1186 }
1187 }
1188 }
1189
Brad Ebingerb78b0232016-10-24 16:40:33 -07001190 /** @see IConnectionService#onCallAudioStateChanged(String, CallAudioState, Session.Info) */
Hall Liuf62630a2015-10-27 14:53:39 -07001191 @VisibleForTesting
1192 public void onCallAudioStateChanged(Call activeCall, CallAudioState audioState) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001193 final String callId = mCallIdMapper.getCallId(activeCall);
Yorke Lee2a66f7b2015-05-13 14:21:19 -07001194 if (callId != null && isServiceValid("onCallAudioStateChanged")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001195 try {
Yorke Lee2a66f7b2015-05-13 14:21:19 -07001196 logOutgoing("onCallAudioStateChanged %s %s", callId, audioState);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001197 mServiceInterface.onCallAudioStateChanged(callId, audioState,
1198 Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001199 } catch (RemoteException e) {
1200 }
1201 }
1202 }
1203
Brad Ebingerb78b0232016-10-24 16:40:33 -07001204 /** @see IConnectionService#disconnect(String, Session.Info) */
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001205 void disconnect(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001206 final String callId = mCallIdMapper.getCallId(call);
1207 if (callId != null && isServiceValid("disconnect")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001208 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001209 logOutgoing("disconnect %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001210 mServiceInterface.disconnect(callId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001211 } catch (RemoteException e) {
1212 }
1213 }
1214 }
1215
Brad Ebingerb78b0232016-10-24 16:40:33 -07001216 /** @see IConnectionService#answer(String, Session.Info) */
Andrew Lee38931d02014-07-16 10:17:36 -07001217 void answer(Call call, int videoState) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001218 final String callId = mCallIdMapper.getCallId(call);
1219 if (callId != null && isServiceValid("answer")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001220 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001221 logOutgoing("answer %s %d", callId, videoState);
Tyler Gunn467b64f2015-06-09 13:48:47 -07001222 if (VideoProfile.isAudioOnly(videoState)) {
Brad Ebingerb78b0232016-10-24 16:40:33 -07001223 mServiceInterface.answer(callId, Log.getExternalSession());
Tyler Gunn041eff62014-08-25 13:52:52 -07001224 } else {
Brad Ebingerb78b0232016-10-24 16:40:33 -07001225 mServiceInterface.answerVideo(callId, videoState, Log.getExternalSession());
Tyler Gunn041eff62014-08-25 13:52:52 -07001226 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001227 } catch (RemoteException e) {
1228 }
1229 }
1230 }
1231
Pooja Jainad4ebc02017-12-28 14:23:13 +05301232 /** @see IConnectionService#deflect(String, Uri , Session.Info) */
1233 void deflect(Call call, Uri address) {
1234 final String callId = mCallIdMapper.getCallId(call);
1235 if (callId != null && isServiceValid("deflect")) {
1236 try {
1237 logOutgoing("deflect %s", callId);
1238 mServiceInterface.deflect(callId, address, Log.getExternalSession());
1239 } catch (RemoteException e) {
1240 }
1241 }
1242 }
1243
Brad Ebingerb78b0232016-10-24 16:40:33 -07001244 /** @see IConnectionService#reject(String, Session.Info) */
Bryce Leeddd966e2015-08-28 16:33:50 -07001245 void reject(Call call, boolean rejectWithMessage, String message) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001246 final String callId = mCallIdMapper.getCallId(call);
1247 if (callId != null && isServiceValid("reject")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001248 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001249 logOutgoing("reject %s", callId);
Bryce Leeddd966e2015-08-28 16:33:50 -07001250
1251 if (rejectWithMessage && call.can(
Hall Liu4b1617a2016-03-14 16:36:08 -07001252 Connection.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION)) {
Brad Ebingerb78b0232016-10-24 16:40:33 -07001253 mServiceInterface.rejectWithMessage(callId, message, Log.getExternalSession());
Bryce Leeddd966e2015-08-28 16:33:50 -07001254 } else {
Brad Ebingerb78b0232016-10-24 16:40:33 -07001255 mServiceInterface.reject(callId, Log.getExternalSession());
Bryce Leeddd966e2015-08-28 16:33:50 -07001256 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001257 } catch (RemoteException e) {
1258 }
1259 }
1260 }
1261
Brad Ebingerb78b0232016-10-24 16:40:33 -07001262 /** @see IConnectionService#playDtmfTone(String, char, Session.Info) */
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001263 void playDtmfTone(Call call, char digit) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001264 final String callId = mCallIdMapper.getCallId(call);
1265 if (callId != null && isServiceValid("playDtmfTone")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001266 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001267 logOutgoing("playDtmfTone %s %c", callId, digit);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001268 mServiceInterface.playDtmfTone(callId, digit, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001269 } catch (RemoteException e) {
1270 }
1271 }
1272 }
1273
Brad Ebingerb78b0232016-10-24 16:40:33 -07001274 /** @see IConnectionService#stopDtmfTone(String, Session.Info) */
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001275 void stopDtmfTone(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001276 final String callId = mCallIdMapper.getCallId(call);
1277 if (callId != null && isServiceValid("stopDtmfTone")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001278 try {
Brad Ebinger11623a32015-11-25 13:52:02 -08001279 logOutgoing("stopDtmfTone %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001280 mServiceInterface.stopDtmfTone(callId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001281 } catch (RemoteException e) {
1282 }
1283 }
1284 }
1285
1286 void addCall(Call call) {
1287 if (mCallIdMapper.getCallId(call) == null) {
1288 mCallIdMapper.addCall(call);
1289 }
1290 }
1291
1292 /**
1293 * Associates newCall with this connection service by replacing callToReplace.
1294 */
1295 void replaceCall(Call newCall, Call callToReplace) {
1296 Preconditions.checkState(callToReplace.getConnectionService() == this);
1297 mCallIdMapper.replaceCall(newCall, callToReplace);
1298 }
1299
1300 void removeCall(Call call) {
Andrew Lee701dc002014-09-11 21:29:12 -07001301 removeCall(call, new DisconnectCause(DisconnectCause.ERROR));
Santos Cordonfd6ca442014-07-24 15:34:01 -07001302 }
1303
Andrew Lee701dc002014-09-11 21:29:12 -07001304 void removeCall(String callId, DisconnectCause disconnectCause) {
Ihab Awadfb5560d2014-08-18 09:32:51 -07001305 CreateConnectionResponse response = mPendingResponses.remove(callId);
1306 if (response != null) {
Andrew Lee701dc002014-09-11 21:29:12 -07001307 response.handleCreateConnectionFailure(disconnectCause);
Ihab Awadfb5560d2014-08-18 09:32:51 -07001308 }
1309
1310 mCallIdMapper.removeCall(callId);
1311 }
1312
Andrew Lee701dc002014-09-11 21:29:12 -07001313 void removeCall(Call call, DisconnectCause disconnectCause) {
Sailesh Nepal664837f2014-07-14 16:31:51 -07001314 CreateConnectionResponse response = mPendingResponses.remove(mCallIdMapper.getCallId(call));
1315 if (response != null) {
Andrew Lee701dc002014-09-11 21:29:12 -07001316 response.handleCreateConnectionFailure(disconnectCause);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001317 }
1318
1319 mCallIdMapper.removeCall(call);
1320 }
1321
1322 void onPostDialContinue(Call call, boolean proceed) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001323 final String callId = mCallIdMapper.getCallId(call);
1324 if (callId != null && isServiceValid("onPostDialContinue")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001325 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001326 logOutgoing("onPostDialContinue %s %b", callId, proceed);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001327 mServiceInterface.onPostDialContinue(callId, proceed, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001328 } catch (RemoteException ignored) {
1329 }
1330 }
1331 }
1332
Santos Cordon0fbe6322014-08-14 04:04:25 -07001333 void conference(final Call call, Call otherCall) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001334 final String callId = mCallIdMapper.getCallId(call);
Santos Cordon0fbe6322014-08-14 04:04:25 -07001335 final String otherCallId = mCallIdMapper.getCallId(otherCall);
1336 if (callId != null && otherCallId != null && isServiceValid("conference")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001337 try {
Santos Cordon0fbe6322014-08-14 04:04:25 -07001338 logOutgoing("conference %s %s", callId, otherCallId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001339 mServiceInterface.conference(callId, otherCallId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001340 } catch (RemoteException ignored) {
1341 }
1342 }
1343 }
1344
1345 void splitFromConference(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -07001346 final String callId = mCallIdMapper.getCallId(call);
1347 if (callId != null && isServiceValid("splitFromConference")) {
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001348 try {
Jay Shrauner969755a2014-08-11 20:34:43 -07001349 logOutgoing("splitFromConference %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001350 mServiceInterface.splitFromConference(callId, Log.getExternalSession());
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001351 } catch (RemoteException ignored) {
1352 }
1353 }
1354 }
1355
Santos Cordon68059232014-09-04 20:09:42 -07001356 void mergeConference(Call call) {
1357 final String callId = mCallIdMapper.getCallId(call);
1358 if (callId != null && isServiceValid("mergeConference")) {
1359 try {
1360 logOutgoing("mergeConference %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001361 mServiceInterface.mergeConference(callId, Log.getExternalSession());
Santos Cordon68059232014-09-04 20:09:42 -07001362 } catch (RemoteException ignored) {
1363 }
1364 }
1365 }
1366
1367 void swapConference(Call call) {
1368 final String callId = mCallIdMapper.getCallId(call);
1369 if (callId != null && isServiceValid("swapConference")) {
1370 try {
1371 logOutgoing("swapConference %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001372 mServiceInterface.swapConference(callId, Log.getExternalSession());
Santos Cordon68059232014-09-04 20:09:42 -07001373 } catch (RemoteException ignored) {
1374 }
1375 }
1376 }
1377
Tyler Gunnd45e6d92016-03-10 20:15:39 -08001378 void pullExternalCall(Call call) {
1379 final String callId = mCallIdMapper.getCallId(call);
1380 if (callId != null && isServiceValid("pullExternalCall")) {
1381 try {
1382 logOutgoing("pullExternalCall %s", callId);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001383 mServiceInterface.pullExternalCall(callId, Log.getExternalSession());
Tyler Gunnd45e6d92016-03-10 20:15:39 -08001384 } catch (RemoteException ignored) {
1385 }
1386 }
1387 }
1388
1389 void sendCallEvent(Call call, String event, Bundle extras) {
1390 final String callId = mCallIdMapper.getCallId(call);
1391 if (callId != null && isServiceValid("sendCallEvent")) {
1392 try {
1393 logOutgoing("sendCallEvent %s %s", callId, event);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001394 mServiceInterface.sendCallEvent(callId, event, extras, Log.getExternalSession());
Tyler Gunnd45e6d92016-03-10 20:15:39 -08001395 } catch (RemoteException ignored) {
1396 }
1397 }
1398 }
1399
Tyler Gunn961694a2016-03-21 16:01:40 -07001400 void onExtrasChanged(Call call, Bundle extras) {
1401 final String callId = mCallIdMapper.getCallId(call);
1402 if (callId != null && isServiceValid("onExtrasChanged")) {
1403 try {
1404 logOutgoing("onExtrasChanged %s %s", callId, extras);
Brad Ebingerb78b0232016-10-24 16:40:33 -07001405 mServiceInterface.onExtrasChanged(callId, extras, Log.getExternalSession());
Tyler Gunn961694a2016-03-21 16:01:40 -07001406 } catch (RemoteException ignored) {
1407 }
1408 }
1409 }
1410
Hall Liuaeece4e2017-02-14 16:42:12 -08001411 void startRtt(Call call, ParcelFileDescriptor fromInCall, ParcelFileDescriptor toInCall) {
1412 final String callId = mCallIdMapper.getCallId(call);
1413 if (callId != null && isServiceValid("startRtt")) {
1414 try {
1415 logOutgoing("startRtt: %s %s %s", callId, fromInCall, toInCall);
1416 mServiceInterface.startRtt(callId, fromInCall, toInCall, Log.getExternalSession());
1417 } catch (RemoteException ignored) {
1418 }
1419 }
1420 }
1421
1422 void stopRtt(Call call) {
1423 final String callId = mCallIdMapper.getCallId(call);
1424 if (callId != null && isServiceValid("stopRtt")) {
1425 try {
1426 logOutgoing("stopRtt: %s", callId);
1427 mServiceInterface.stopRtt(callId, Log.getExternalSession());
1428 } catch (RemoteException ignored) {
1429 }
1430 }
1431 }
1432
1433 void respondToRttRequest(
1434 Call call, ParcelFileDescriptor fromInCall, ParcelFileDescriptor toInCall) {
1435 final String callId = mCallIdMapper.getCallId(call);
1436 if (callId != null && isServiceValid("respondToRttRequest")) {
1437 try {
1438 logOutgoing("respondToRttRequest: %s %s %s", callId, fromInCall, toInCall);
1439 mServiceInterface.respondToRttUpgradeRequest(
1440 callId, fromInCall, toInCall, Log.getExternalSession());
1441 } catch (RemoteException ignored) {
1442 }
1443 }
1444 }
1445
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001446 /** {@inheritDoc} */
1447 @Override
1448 protected void setServiceInterface(IBinder binder) {
Brad Ebinger6e8f3d72016-06-20 11:35:42 -07001449 mServiceInterface = IConnectionService.Stub.asInterface(binder);
1450 Log.v(this, "Adding Connection Service Adapter.");
1451 addConnectionServiceAdapter(mAdapter);
1452 }
1453
1454 /** {@inheritDoc} */
1455 @Override
1456 protected void removeServiceInterface() {
1457 Log.v(this, "Removing Connection Service Adapter.");
1458 removeConnectionServiceAdapter(mAdapter);
1459 // We have lost our service connection. Notify the world that this service is done.
1460 // We must notify the adapter before CallsManager. The adapter will force any pending
1461 // outgoing calls to try the next service. This needs to happen before CallsManager
1462 // tries to clean up any calls still associated with this service.
1463 handleConnectionServiceDeath();
1464 mCallsManager.handleConnectionServiceDeath(this);
1465 mServiceInterface = null;
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001466 }
1467
Pengquan Mengd7f92cf2017-11-21 17:52:42 -08001468 @Override
1469 public void connectionServiceFocusLost() {
1470 // Immediately response to the Telecom that it has released the call resources.
1471 // TODO(mpq): Change back to the default implementation once b/69651192 done.
1472 if (mConnSvrFocusListener != null) {
Pengquan Meng4832f202017-12-20 16:13:04 -08001473 mConnSvrFocusListener.onConnectionServiceReleased(ConnectionServiceWrapper.this);
Pengquan Mengd7f92cf2017-11-21 17:52:42 -08001474 }
Pengquan Meng4832f202017-12-20 16:13:04 -08001475 BindCallback callback = new BindCallback() {
1476 @Override
1477 public void onSuccess() {
1478 try {
1479 mServiceInterface.connectionServiceFocusLost(Log.getExternalSession());
1480 } catch (RemoteException ignored) {
1481 Log.d(this, "failed to inform the focus lost event");
1482 }
1483 }
1484
1485 @Override
1486 public void onFailure() {}
1487 };
1488 mBinder.bind(callback, null /* null call */);
Pengquan Mengd7f92cf2017-11-21 17:52:42 -08001489 }
1490
1491 @Override
Pengquan Meng4832f202017-12-20 16:13:04 -08001492 public void connectionServiceFocusGained() {
1493 BindCallback callback = new BindCallback() {
1494 @Override
1495 public void onSuccess() {
1496 try {
1497 mServiceInterface.connectionServiceFocusGained(Log.getExternalSession());
1498 } catch (RemoteException ignored) {
1499 Log.d(this, "failed to inform the focus gained event");
1500 }
1501 }
1502
1503 @Override
1504 public void onFailure() {}
1505 };
1506 mBinder.bind(callback, null /* null call */);
1507 }
Pengquan Mengd7f92cf2017-11-21 17:52:42 -08001508
1509 @Override
1510 public void setConnectionServiceFocusListener(
1511 ConnectionServiceFocusManager.ConnectionServiceFocusListener listener) {
1512 mConnSvrFocusListener = listener;
1513 }
1514
Ihab Awadfb5560d2014-08-18 09:32:51 -07001515 private void handleCreateConnectionComplete(
1516 String callId,
1517 ConnectionRequest request,
1518 ParcelableConnection connection) {
1519 // TODO: Note we are not using parameter "request", which is a side effect of our tacit
1520 // assumption that we have at most one outgoing connection attempt per ConnectionService.
1521 // This may not continue to be the case.
1522 if (connection.getState() == Connection.STATE_DISCONNECTED) {
1523 // A connection that begins in the DISCONNECTED state is an indication of
1524 // failure to connect; we handle all failures uniformly
Andrew Lee701dc002014-09-11 21:29:12 -07001525 removeCall(callId, connection.getDisconnectCause());
Ihab Awadfb5560d2014-08-18 09:32:51 -07001526 } else {
1527 // Successful connection
1528 if (mPendingResponses.containsKey(callId)) {
Ihab Awad80008452014-08-23 20:35:44 -07001529 mPendingResponses.remove(callId)
1530 .handleCreateConnectionSuccess(mCallIdMapper, connection);
Ihab Awadfb5560d2014-08-18 09:32:51 -07001531 }
1532 }
1533 }
1534
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001535 /**
1536 * Called when the associated connection service dies.
1537 */
1538 private void handleConnectionServiceDeath() {
Sailesh Nepal664837f2014-07-14 16:31:51 -07001539 if (!mPendingResponses.isEmpty()) {
1540 CreateConnectionResponse[] responses = mPendingResponses.values().toArray(
1541 new CreateConnectionResponse[mPendingResponses.values().size()]);
1542 mPendingResponses.clear();
1543 for (int i = 0; i < responses.length; i++) {
Andrew Lee701dc002014-09-11 21:29:12 -07001544 responses[i].handleCreateConnectionFailure(
Tyler Gunn1a97fb22017-06-21 19:55:54 -07001545 new DisconnectCause(DisconnectCause.ERROR, "CS_DEATH"));
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001546 }
1547 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001548 mCallIdMapper.clear();
Pengquan Mengd7f92cf2017-11-21 17:52:42 -08001549
1550 if (mConnSvrFocusListener != null) {
1551 mConnSvrFocusListener.onConnectionServiceDeath(this);
1552 }
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001553 }
1554
1555 private void logIncoming(String msg, Object... params) {
Tyler Gunn9b618b82016-10-17 15:54:35 -07001556 Log.d(this, "ConnectionService -> Telecom[" + mComponentName.flattenToShortString() + "]: "
Tyler Gunn46bc3fd2017-04-03 18:53:38 +00001557 + msg, params);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001558 }
1559
1560 private void logOutgoing(String msg, Object... params) {
Tyler Gunn9b618b82016-10-17 15:54:35 -07001561 Log.d(this, "Telecom -> ConnectionService[" + mComponentName.flattenToShortString() + "]: "
Tyler Gunn46bc3fd2017-04-03 18:53:38 +00001562 + msg, params);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001563 }
1564
Tony Mak240656f2015-12-04 11:36:22 +00001565 private void queryRemoteConnectionServices(final UserHandle userHandle,
1566 final RemoteServiceCallback callback) {
Ihab Awadb78b2762014-07-25 15:16:23 -07001567 // Only give remote connection services to this connection service if it is listed as
1568 // the connection manager.
Tony Mak240656f2015-12-04 11:36:22 +00001569 PhoneAccountHandle simCallManager = mPhoneAccountRegistrar.getSimCallManager(userHandle);
Ihab Awadc17294c2014-08-04 19:23:37 -07001570 Log.d(this, "queryRemoteConnectionServices finds simCallManager = %s", simCallManager);
Ihab Awadb78b2762014-07-25 15:16:23 -07001571 if (simCallManager == null ||
1572 !simCallManager.getComponentName().equals(getComponentName())) {
1573 noRemoteServices(callback);
1574 return;
1575 }
Sailesh Nepal664837f2014-07-14 16:31:51 -07001576
Ihab Awadb78b2762014-07-25 15:16:23 -07001577 // Make a list of ConnectionServices that are listed as being associated with SIM accounts
Jay Shraunera82c8f72014-08-14 15:49:16 -07001578 final Set<ConnectionServiceWrapper> simServices = Collections.newSetFromMap(
1579 new ConcurrentHashMap<ConnectionServiceWrapper, Boolean>(8, 0.9f, 1));
Tony Mak240656f2015-12-04 11:36:22 +00001580 for (PhoneAccountHandle handle : mPhoneAccountRegistrar.getSimPhoneAccounts(userHandle)) {
Santos Cordon6a212642015-05-08 16:35:23 -07001581 ConnectionServiceWrapper service = mConnectionServiceRepository.getService(
1582 handle.getComponentName(), handle.getUserHandle());
1583 if (service != null) {
1584 simServices.add(service);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001585 }
Sailesh Nepal905dfba2014-07-14 08:20:41 -07001586 }
Ihab Awadb78b2762014-07-25 15:16:23 -07001587
1588 final List<ComponentName> simServiceComponentNames = new ArrayList<>();
1589 final List<IBinder> simServiceBinders = new ArrayList<>();
1590
1591 Log.v(this, "queryRemoteConnectionServices, simServices = %s", simServices);
1592
1593 for (ConnectionServiceWrapper simService : simServices) {
1594 if (simService == this) {
1595 // Only happens in the unlikely case that a SIM service is also a SIM call manager
1596 continue;
1597 }
1598
1599 final ConnectionServiceWrapper currentSimService = simService;
1600
1601 currentSimService.mBinder.bind(new BindCallback() {
1602 @Override
1603 public void onSuccess() {
1604 Log.d(this, "Adding simService %s", currentSimService.getComponentName());
Tyler Gunn5983dc12018-03-08 23:22:31 +00001605 if (currentSimService.mServiceInterface == null) {
1606 // The remote ConnectionService died, so do not add it.
1607 // We will still perform maybeComplete() and notify the caller with an empty
1608 // list of sim services via maybeComplete().
1609 Log.w(this, "queryRemoteConnectionServices: simService %s died - Skipping.",
1610 currentSimService.getComponentName());
1611 } else {
1612 simServiceComponentNames.add(currentSimService.getComponentName());
1613 simServiceBinders.add(currentSimService.mServiceInterface.asBinder());
1614 }
Ihab Awadb78b2762014-07-25 15:16:23 -07001615 maybeComplete();
1616 }
1617
1618 @Override
1619 public void onFailure() {
1620 Log.d(this, "Failed simService %s", currentSimService.getComponentName());
1621 // We know maybeComplete() will always be a no-op from now on, so go ahead and
1622 // signal failure of the entire request
1623 noRemoteServices(callback);
1624 }
1625
1626 private void maybeComplete() {
1627 if (simServiceComponentNames.size() == simServices.size()) {
1628 setRemoteServices(callback, simServiceComponentNames, simServiceBinders);
1629 }
1630 }
Santos Cordon165c1ce2015-07-10 16:07:59 -07001631 }, null);
Ihab Awadb78b2762014-07-25 15:16:23 -07001632 }
1633 }
1634
1635 private void setRemoteServices(
1636 RemoteServiceCallback callback,
1637 List<ComponentName> componentNames,
1638 List<IBinder> binders) {
1639 try {
1640 callback.onResult(componentNames, binders);
1641 } catch (RemoteException e) {
1642 Log.e(this, e, "Contacting ConnectionService %s",
1643 ConnectionServiceWrapper.this.getComponentName());
1644 }
1645 }
1646
1647 private void noRemoteServices(RemoteServiceCallback callback) {
Ihab Awad8de76912015-02-17 12:25:52 -08001648 setRemoteServices(callback, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
Sailesh Nepalc92c4362014-07-04 18:33:21 -07001649 }
1650}