163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon/*
263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Copyright 2014, The Android Open Source Project
363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *
463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * you may not use this file except in compliance with the License.
663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * You may obtain a copy of the License at
763aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *
863aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *     http://www.apache.org/licenses/LICENSE-2.0
963aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon *
1063aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * Unless required by applicable law or agreed to in writing, software
1163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
1263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * See the License for the specific language governing permissions and
1463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon * limitations under the License.
1563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon */
1663aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom;
1863aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
19913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebingerimport android.app.AppOpsManager;
205924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordonimport android.content.ComponentName;
2191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport android.content.Context;
22e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepalimport android.net.Uri;
23512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awadimport android.os.Binder;
24a05805b839edea9b9fe3bd4a0fbaf310c2a32838Evan Charltonimport android.os.Bundle;
2563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordonimport android.os.IBinder;
26aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liuimport android.os.ParcelFileDescriptor;
2763aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordonimport android.os.RemoteException;
28105d977687d1d0de7cd9420fc140b01404261df1Evan Charltonimport android.os.UserHandle;
292a66f7b906b225413ae33f72e70a75e4f9c883c0Yorke Leeimport android.telecom.CallAudioState;
307cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Connection;
317cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ConnectionRequest;
327cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ConnectionService;
33701dc006ac11625b55d872f1639107b028933895Andrew Leeimport android.telecom.DisconnectCause;
347cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.GatewayInfo;
35953e1af643b66df6f931d76c23bcc54147668cd4Brad Ebingerimport android.telecom.Log;
36b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebingerimport android.telecom.Logging.Session;
377cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ParcelableConference;
387cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ParcelableConnection;
397cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccountHandle;
407cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.StatusHints;
417cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.TelecomManager;
427cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.VideoProfile;
43a439e1b6d6201dedecfc40b67c9347a8c563b9c1Sailesh Nepal
44f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liuimport com.android.internal.annotations.VisibleForTesting;
457cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.internal.telecom.IConnectionService;
467cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.internal.telecom.IConnectionServiceAdapter;
477cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.internal.telecom.IVideoProvider;
487cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.internal.telecom.RemoteServiceCallback;
4991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport com.android.internal.util.Preconditions;
503d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
515924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordonimport java.util.ArrayList;
52b78b27693afbe9736f0a54ec473328955251f885Ihab Awadimport java.util.Collections;
53682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordonimport java.util.HashMap;
548f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordonimport java.util.List;
55682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordonimport java.util.Map;
563d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordonimport java.util.Set;
57a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shraunerimport java.util.concurrent.ConcurrentHashMap;
5863aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
5963aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon/**
60c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * Wrapper for {@link IConnectionService}s, handles binding to {@link IConnectionService} and keeps
61c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * track of when the object can safely be unbound. Other classes should not use
62c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * {@link IConnectionService} directly and instead should use this class to invoke methods of
63c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * {@link IConnectionService}.
6463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon */
65f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu@VisibleForTesting
66f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liupublic class ConnectionServiceWrapper extends ServiceBinder {
67c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
68c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    private final class Adapter extends IConnectionServiceAdapter.Stub {
696fb37c87836b5245046bd3b14320823ab839a10cIhab Awad
703d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
7111623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger        public void handleCreateConnectionComplete(String callId, ConnectionRequest request,
7265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                ParcelableConnection connection, Session.Info sessionInfo) {
7365912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_HANDLE_CREATE_CONNECTION_COMPLETE);
74512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
75512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
76512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
77512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("handleCreateConnectionComplete %s", callId);
788452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    ConnectionServiceWrapper.this
798452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                            .handleCreateConnectionComplete(callId, request, connection);
80ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn
81ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                    if (mServiceInterface != null) {
82ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                        logOutgoing("createConnectionComplete %s", callId);
83ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                        try {
84ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                            mServiceInterface.createConnectionComplete(callId,
85ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                                    Log.getExternalSession());
86ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                        } catch (RemoteException e) {
87ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                        }
88ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                    }
898d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
90512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
91512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
9211623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
93969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
943d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
953d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
963d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
9765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setActive(String callId, Session.Info sessionInfo) {
9865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_ACTIVE);
99512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
100512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
101512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
102512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setActive %s", callId);
1038452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
1048452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
1058452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        mCallsManager.markCallAsActive(call);
1068452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
1078452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "setActive, unknown call id: %s", msg.obj);
1088d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
1098d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
110512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
111512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
11211623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
113969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
1143d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
1153d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1163d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
11765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setRinging(String callId, Session.Info sessionInfo) {
11865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_RINGING);
119512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
120512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
121512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
122512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setRinging %s", callId);
1238452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
1248452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
1258452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        mCallsManager.markCallAsRinging(call);
1268452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
1278452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "setRinging, unknown call id: %s", msg.obj);
1288d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
1298d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
130512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
131512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
13211623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
133969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
1343d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
1353d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1363d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
13765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setVideoProvider(String callId, IVideoProvider videoProvider,
13865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
13965912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sVP");
140512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
141512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
142512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
143512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setVideoProvider %s", callId);
1448452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
1458452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
1468452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setVideoProvider(videoProvider);
1478d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
1488d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
149512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
150512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
15111623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
152969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
153e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee        }
154e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee
155e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee        @Override
15665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setDialing(String callId, Session.Info sessionInfo) {
15765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_DIALING);
158512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
159512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
160512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
161512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setDialing %s", callId);
1628452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
1638452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
1648452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        mCallsManager.markCallAsDialing(call);
1658452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
1668452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "setDialing, unknown call id: %s", msg.obj);
1678d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
1688d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
169512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
170512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
17111623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
172969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
1733d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
1743d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1753d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
17665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger	    public void setPulling(String callId, Session.Info sessionInfo) {
17765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_PULLING);
1781e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            long token = Binder.clearCallingIdentity();
1791e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            try {
1801e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                synchronized (mLock) {
1811e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    logIncoming("setPulling %s", callId);
1821e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
1831e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    if (call != null) {
1841e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                        mCallsManager.markCallAsPulling(call);
1851e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    }
1861e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                }
1871e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            } finally {
1881e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                Binder.restoreCallingIdentity(token);
1891e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                Log.endSession();
1901e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            }
1911e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        }
1921e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn
1931e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        @Override
19465912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setDisconnected(String callId, DisconnectCause disconnectCause,
19565912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
19665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_DISCONNECTED);
197512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
198512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
199512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
200512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setDisconnected %s %s", callId, disconnectCause);
2018452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
2028452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Log.d(this, "disconnect call %s %s", disconnectCause, call);
2038452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
2048452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        mCallsManager.markCallAsDisconnected(call, disconnectCause);
2058452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
2068452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
2078d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
2088d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
209512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
210512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
21111623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
212969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
2133d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
2143d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
2153d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        @Override
21665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setOnHold(String callId, Session.Info sessionInfo) {
21765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_ON_HOLD);
218512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
219512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
220512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
221512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setOnHold %s", callId);
2228452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
2238452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
2248452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        mCallsManager.markCallAsOnHold(call);
2258452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
2268452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
2278d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
2288d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
229512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
230512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
23111623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
232969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
2333d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon        }
23450a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad
23550a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        @Override
23665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setRingbackRequested(String callId, boolean ringback,
23765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
23865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.SRR");
239512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
240512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
241512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
242512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setRingbackRequested %s %b", callId, ringback);
2438452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
2448452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
2458452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setRingbackRequested(ringback);
2468452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
2478452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "setRingback, unknown call id: %s", args.arg1);
2488d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
2498d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
250512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
251512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
25211623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
253969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
25450a57136b3aa876c8311b58e1e11720a337fe1ccIhab Awad        }
2558f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon
2568f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon        @Override
25765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void removeCall(String callId, Session.Info sessionInfo) {
25865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_REMOVE_CALL);
259512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
260512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
261512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
262512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("removeCall %s", callId);
2638452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
2648452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
2658452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        if (call.isAlive()) {
2668452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                            mCallsManager.markCallAsDisconnected(
2678452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                                    call, new DisconnectCause(DisconnectCause.REMOTE));
2688452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        } else {
2698452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                            mCallsManager.markCallAsRemoved(call);
2708d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                        }
2718d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
2728d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
273512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
274512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
27511623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
276a02bef5d67f261d7457d0dab9e51595f1960128bIhab Awad            }
2778f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon        }
2788f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon
2798f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon        @Override
28065912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setConnectionCapabilities(String callId, int connectionCapabilities,
28165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
28265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sCC");
283512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
284512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
285512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
286512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setConnectionCapabilities %s %d", callId, connectionCapabilities);
2878452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
2888452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
2898452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setConnectionCapabilities(connectionCapabilities);
2908452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
2918452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(ConnectionServiceWrapper.this,
2928452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // "setConnectionCapabilities, unknown call id: %s", msg.obj);
2938d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
2948d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
295512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
296512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
29711623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
298969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
2998f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon        }
3008f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon
3018f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon        @Override
30265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setConnectionProperties(String callId, int connectionProperties,
30365912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
304571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn            Log.startSession("CSW.sCP");
305571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn            long token = Binder.clearCallingIdentity();
306571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn            try {
307571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                synchronized (mLock) {
308571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                    logIncoming("setConnectionProperties %s %d", callId, connectionProperties);
309571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
310571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                    if (call != null) {
311571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                        call.setConnectionProperties(connectionProperties);
312571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                    }
313571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                }
314571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn            } finally {
315571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                Binder.restoreCallingIdentity(token);
316571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn                Log.endSession();
317571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn            }
318571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        }
319571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn
320571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        @Override
32165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setIsConferenced(String callId, String conferenceCallId,
32265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
32365912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_SET_IS_CONFERENCED);
324512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
325512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
326512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
327512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
328512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    Call childCall = mCallIdMapper.getCall(callId);
329512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    if (childCall != null) {
330512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        if (conferenceCallId == null) {
331512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                            Log.d(this, "unsetting parent: %s", conferenceCallId);
3327658171d6d496686263d0fc9da55a0ed7a61f818Tyler Gunn                            childCall.setParentAndChildCall(null);
333512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        } else {
334512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                            Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
3357658171d6d496686263d0fc9da55a0ed7a61f818Tyler Gunn                            childCall.setParentAndChildCall(conferenceCall);
336512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        }
3378d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    } else {
338512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        // Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
3398d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
3408d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
341512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
342512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
34311623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
3448d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad            }
345a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
346a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
347a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        @Override
34865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setConferenceMergeFailed(String callId, Session.Info sessionInfo) {
34965912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sCMF");
350ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee            long token = Binder.clearCallingIdentity();
351ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee            try {
352ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee                synchronized (mLock) {
353ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee                    logIncoming("setConferenceMergeFailed %s", callId);
3548452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    // TODO: we should move the UI for indication a merge failure here
3558452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    // from CallNotifier.onSuppServiceFailed(). This way the InCallUI can
3568452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    // deliver the message anyway that they want. b/20530631.
3578452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
3588452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
3590d40255032680d3cce56a07f7eba8baefc5512cdBrad Ebinger                        call.onConnectionEvent(Connection.EVENT_CALL_MERGE_FAILED, null);
3608452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
3618452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        Log.w(this, "setConferenceMergeFailed, unknown call id: %s", callId);
362ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee                    }
363ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee                }
364ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee            } finally {
365ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee                Binder.restoreCallingIdentity(token);
36611623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
367ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee            }
368ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee        }
369ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee
370ce75aa1cfa3572f208d02a058b7aaf025ad6856cAnthony Lee        @Override
37165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void addConferenceCall(String callId, ParcelableConference parcelableConference,
37265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
37365912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL);
374512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
375512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
376512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
377512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    if (mCallIdMapper.getCall(callId) != null) {
378512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        Log.w(this, "Attempting to add a conference call using an existing " +
379512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                                "call id %s", callId);
380512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        return;
381512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    }
3829b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    logIncoming("addConferenceCall %s %s [%s]", callId, parcelableConference,
3839b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            parcelableConference.getConnectionIds());
3848d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad
385512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    // Make sure that there's at least one valid call. For remote connections
386512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    // we'll get a add conference msg from both the remote connection service
387512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    // and from the real connection service.
388512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    boolean hasValidCalls = false;
389512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    for (String connId : parcelableConference.getConnectionIds()) {
390512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        if (mCallIdMapper.getCall(connId) != null) {
391512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                            hasValidCalls = true;
392512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        }
393512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    }
394512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    // But don't bail out if the connection count is 0, because that is a valid
395512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    // IMS conference state.
396512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    if (!hasValidCalls && parcelableConference.getConnectionIds().size() > 0) {
397512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        Log.d(this, "Attempting to add a conference with no valid calls");
398512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        return;
3998d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
4008d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad
401512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    PhoneAccountHandle phAcc = null;
402512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    if (parcelableConference != null &&
403512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                            parcelableConference.getPhoneAccount() != null) {
404512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        phAcc = parcelableConference.getPhoneAccount();
405512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    }
4069b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
4079b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    Bundle connectionExtras = parcelableConference.getExtras();
4089b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
4099b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    String connectIdToCheck = null;
4109b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    if (connectionExtras != null && connectionExtras
4119b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
4129b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // Conference was added via a connection manager, see if its original id is
4139b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // known.
4149b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        connectIdToCheck = connectionExtras
4159b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                .getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
4169b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    } else {
4179b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        connectIdToCheck = callId;
4189b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    }
4199b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
4209b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    Call conferenceCall;
4219b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    // Check to see if this conference has already been added.
4229b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    Call alreadyAddedConnection = mCallsManager
4239b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            .getAlreadyAddedConnection(connectIdToCheck);
4249b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    if (alreadyAddedConnection != null && mCallIdMapper.getCall(callId) == null) {
4259b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // We are currently attempting to add the conference via a connection mgr,
4269b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // and the originating ConnectionService has already added it.  Instead of
4279b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // making a new Telecom call, we will simply add it to the ID mapper here,
4289b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // and replace the ConnectionService on the call.
4299b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        mCallIdMapper.addCall(alreadyAddedConnection, callId);
4309b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        alreadyAddedConnection.replaceConnectionService(
4319b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                ConnectionServiceWrapper.this);
4329b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        conferenceCall = alreadyAddedConnection;
4339b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    } else {
4349b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // need to create a new Call
4359b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        Call newConferenceCall = mCallsManager.createConferenceCall(callId,
4369b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                phAcc, parcelableConference);
4379b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        mCallIdMapper.addCall(newConferenceCall, callId);
4389b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        newConferenceCall.setConnectionService(ConnectionServiceWrapper.this);
4399b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        conferenceCall = newConferenceCall;
4409b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    }
441512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad
442512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    Log.d(this, "adding children to conference %s phAcc %s",
443512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                            parcelableConference.getConnectionIds(), phAcc);
444512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    for (String connId : parcelableConference.getConnectionIds()) {
445512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        Call childCall = mCallIdMapper.getCall(connId);
446512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        Log.d(this, "found child: %s", connId);
447512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        if (childCall != null) {
4487658171d6d496686263d0fc9da55a0ed7a61f818Tyler Gunn                            childCall.setParentAndChildCall(conferenceCall);
449512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                        }
4508d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
4518d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
452512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
453512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
45411623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
4558d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad            }
4568f3282c49bd4e8e6de59be4bdaefc726d99a3273Santos Cordon        }
457352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton
458352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton        @Override
45965912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void onPostDialWait(String callId, String remaining,
46065912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) throws RemoteException {
46165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.oPDW");
462512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
463512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
464512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
465512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("onPostDialWait %s %s", callId, remaining);
4668452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
4678452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
4688452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.onPostDialWait(remaining);
4698452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
4708452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
4718d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
4728d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
473512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
474512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
47511623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
476969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
477352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton        }
4786098d2c392f8698f8f4885da6edf6c5b8d7e4cb9Sailesh Nepal
4795924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon        @Override
48065912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void onPostDialChar(String callId, char nextChar,
48165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) throws RemoteException {
48265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.oPDC");
483512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
484512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
485512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
486512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("onPostDialChar %s %s", callId, nextChar);
4878452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
4888452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
4898452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.onPostDialChar(nextChar);
4908452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    } else {
4918452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        // Log.w(this, "onPostDialChar, unknown call id: %s", args.arg1);
4928d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
4938d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
494512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
495512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
49611623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
497a469f76c1710a945933910840f11f9fda0445d82Nancy Chen            }
498a469f76c1710a945933910840f11f9fda0445d82Nancy Chen        }
499a469f76c1710a945933910840f11f9fda0445d82Nancy Chen
500a469f76c1710a945933910840f11f9fda0445d82Nancy Chen        @Override
50165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void queryRemoteConnectionServices(RemoteServiceCallback callback,
50265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
503240656f19c078b4f703d0502ce29114de0d45a50Tony Mak            final UserHandle callingUserHandle = Binder.getCallingUserHandle();
50465912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.qRCS");
505512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
506512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
507512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
508512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("queryRemoteConnectionServices %s", callback);
509240656f19c078b4f703d0502ce29114de0d45a50Tony Mak                    ConnectionServiceWrapper.this
510240656f19c078b4f703d0502ce29114de0d45a50Tony Mak                            .queryRemoteConnectionServices(callingUserHandle, callback);
511512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                }
512512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
513512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
51411623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
5158d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad            }
5165924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon        }
517e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn
518e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn        @Override
51965912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setVideoState(String callId, int videoState, Session.Info sessionInfo) {
52065912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sVS");
521512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
522512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
523512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
524512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setVideoState %s %d", callId, videoState);
5258452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
5268452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
5278452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setVideoState(videoState);
5288d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
5298d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
530512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
531512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
53211623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
533969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
5340a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn        }
5350a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn
5360a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn        @Override
53765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setIsVoipAudioMode(String callId, boolean isVoip, Session.Info sessionInfo) {
53865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sIVAM");
539512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
540512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
541512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
542512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setIsVoipAudioMode %s %b", callId, isVoip);
5438452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
5448452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
5458452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setIsVoipAudioMode(isVoip);
5468d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
5478d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
548512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
549512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
55011623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
551969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
5527e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal        }
55335faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal
55435faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        @Override
555acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn        public void setAudioRoute(String callId, int audioRoute, Session.Info sessionInfo) {
556acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn            Log.startSession(sessionInfo, "CSW.sAR");
557acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn            long token = Binder.clearCallingIdentity();
558acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn            try {
559acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                synchronized (mLock) {
560acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                    logIncoming("setAudioRoute %s %s", callId,
561acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                            CallAudioState.audioRouteToString(audioRoute));
562acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                    mCallsManager.setAudioRoute(audioRoute);
563acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                }
564acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn            } finally {
565acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                Binder.restoreCallingIdentity(token);
566acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn                Log.endSession();
567acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn            }
568acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn        }
569acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn
570acb3bc8474e7cdb9c6ef4f0b23c227f6ed55d356Tyler Gunn        @Override
57165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setStatusHints(String callId, StatusHints statusHints,
57265912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
57365912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sSH");
574512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
575512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
576512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
577512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setStatusHints %s %s", callId, statusHints);
5788452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
5798452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
5808452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setStatusHints(statusHints);
5818d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
5828d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
583512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
584512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
58511623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
586969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
58735faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        }
588e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
589e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        @Override
59065912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void putExtras(String callId, Bundle extras, Session.Info sessionInfo) {
59165912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.pE");
592b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon            long token = Binder.clearCallingIdentity();
593b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon            try {
59411623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                synchronized (mLock) {
595e2e4cdff6dd167ea1ede3eb6ee53468b9a32f0afJeff Sharkey                    Bundle.setDefusable(extras, true);
5968452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
5978452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
598961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                        call.putExtras(Call.SOURCE_CONNECTION_SERVICE, extras);
599961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                    }
600961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                }
601961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            } finally {
602961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                Binder.restoreCallingIdentity(token);
603961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                Log.endSession();
604961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            }
605961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        }
606961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn
607961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        @Override
60865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void removeExtras(String callId, List<String> keys, Session.Info sessionInfo) {
60965912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.rE");
610961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            long token = Binder.clearCallingIdentity();
611961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            try {
612961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                synchronized (mLock) {
613961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                    logIncoming("removeExtra %s %s", callId, keys);
614961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
615961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                    if (call != null) {
616961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                        call.removeExtras(Call.SOURCE_CONNECTION_SERVICE, keys);
617b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon                    }
618b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon                }
619b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon            } finally {
620b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon                Binder.restoreCallingIdentity(token);
62111623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
622b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon            }
623b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon        }
624b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon
625b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon        @Override
62665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setAddress(String callId, Uri address, int presentation,
62765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
62865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sA");
629512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
630512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
631512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
632512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setAddress %s %s %d", callId, address, presentation);
6338452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
6348452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
6358452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setHandle(address, presentation);
6368d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
6378d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
638512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
639512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
64011623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
641969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
642e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        }
643e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
644e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        @Override
64565912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setCallerDisplayName(String callId, String callerDisplayName, int presentation,
64665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
64765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sCDN");
648512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
649512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
650512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
651512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                    logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName,
652512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                            presentation);
6538452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
6548452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
6558452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setCallerDisplayName(callerDisplayName, presentation);
6568d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
6578d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
658512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
659512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
66011623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
661969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
662e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        }
6639d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal
6649d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal        @Override
66565912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void setConferenceableConnections(String callId, List<String> conferenceableCallIds,
66665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
66765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.sCC");
668512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
669512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
670512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
6719b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
6728452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
6738452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                    if (call != null) {
6749b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        logIncoming("setConferenceableConnections %s %s", callId,
6759b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                conferenceableCallIds);
6768452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        List<Call> conferenceableCalls =
6778452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                                new ArrayList<>(conferenceableCallIds.size());
6788452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        for (String otherId : conferenceableCallIds) {
6798452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                            Call otherCall = mCallIdMapper.getCall(otherId);
6808452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                            if (otherCall != null && otherCall != call) {
6818452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                                conferenceableCalls.add(otherCall);
6828d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                            }
6838d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                        }
6848452be0e1e82e0d12cfb884bbf683ec5f95c9781Tyler Gunn                        call.setConferenceableCalls(conferenceableCalls);
6858d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                    }
6868d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad                }
687512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
688512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
68911623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
690969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner            }
69112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        }
6926e2b94eae72c72b11358fdb99f87471b5ab11e4fTyler Gunn
6936e2b94eae72c72b11358fdb99f87471b5ab11e4fTyler Gunn        @Override
69465912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger	public void addExistingConnection(String callId, ParcelableConnection connection,
69565912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger	        Session.Info sessionInfo) {
69665912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.aEC");
697913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger            UserHandle userHandle = Binder.getCallingUserHandle();
698913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger            // Check that the Calling Package matches PhoneAccountHandle's Component Package
699913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger            PhoneAccountHandle callingPhoneAccountHandle = connection.getPhoneAccount();
700913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger            if (callingPhoneAccountHandle != null) {
701913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                mAppOpsManager.checkPackage(Binder.getCallingUid(),
702913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        callingPhoneAccountHandle.getComponentName().getPackageName());
703913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger            }
704512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            long token = Binder.clearCallingIdentity();
705512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            try {
706512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                synchronized (mLock) {
707913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    // Make sure that the PhoneAccount associated with the incoming
708913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    // ParcelableConnection is in fact registered to Telecom and is being called
709913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    // from the correct user.
710913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    List<PhoneAccountHandle> accountHandles =
711913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                            mPhoneAccountRegistrar.getCallCapablePhoneAccounts(null /*uriScheme*/,
712913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                                    false /*includeDisabledAccounts*/, userHandle);
713913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    PhoneAccountHandle phoneAccountHandle = null;
714913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    for (PhoneAccountHandle accountHandle : accountHandles) {
715913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        if(accountHandle.equals(callingPhoneAccountHandle)) {
716913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                            phoneAccountHandle = accountHandle;
717913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        }
718913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    }
7199b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    // Allow the Sim call manager account as well, even if its disabled.
7209b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    if (phoneAccountHandle == null && callingPhoneAccountHandle != null) {
7219b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        if (callingPhoneAccountHandle.equals(
7229b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                mPhoneAccountRegistrar.getSimCallManager(userHandle))) {
7239b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            phoneAccountHandle = callingPhoneAccountHandle;
7249b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        }
7259b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                    }
726913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    if (phoneAccountHandle != null) {
7279b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        logIncoming("addExistingConnection %s %s", callId, connection);
7289b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
7299b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        Bundle connectionExtras = connection.getExtras();
7309b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        String connectIdToCheck = null;
7319b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        if (connectionExtras != null && connectionExtras
7329b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) {
7339b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            connectIdToCheck = connectionExtras
7349b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                    .getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID);
7359b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        } else {
7369b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            connectIdToCheck = callId;
7379b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        }
7389b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        // Check to see if this Connection has already been added.
7399b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        Call alreadyAddedConnection = mCallsManager
7409b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                .getAlreadyAddedConnection(connectIdToCheck);
7419b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
7429b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        if (alreadyAddedConnection != null
7439b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                && mCallIdMapper.getCall(callId) == null) {
7449b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            mCallIdMapper.addCall(alreadyAddedConnection, callId);
7459b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            alreadyAddedConnection
7469b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                                    .replaceConnectionService(ConnectionServiceWrapper.this);
7479b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                            return;
7489b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn                        }
7499b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn
750913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        Call existingCall = mCallsManager
751913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                                .createCallForExistingConnection(callId, connection);
752913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        mCallIdMapper.addCall(existingCall, callId);
753913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        existingCall.setConnectionService(ConnectionServiceWrapper.this);
754913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    } else {
755913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                        Log.e(this, new RemoteException("The PhoneAccount being used is not " +
756913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                                "currently registered with Telecom."), "Unable to " +
757913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                                "addExistingConnection.");
758913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger                    }
759512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                }
760512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad            } finally {
761512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad                Binder.restoreCallingIdentity(token);
76211623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                Log.endSession();
7638d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad            }
7646e2b94eae72c72b11358fdb99f87471b5ab11e4fTyler Gunn        }
765db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn
766db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn        @Override
76765912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger        public void onConnectionEvent(String callId, String event, Bundle extras,
76865912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger                Session.Info sessionInfo) {
76965912759cdf64aa5a38f5498f22c8b5ba8a97ebeBrad Ebinger            Log.startSession(sessionInfo, "CSW.oCE");
770db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn            long token = Binder.clearCallingIdentity();
771db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn            try {
772db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                synchronized (mLock) {
773e2e4cdff6dd167ea1ede3eb6ee53468b9a32f0afJeff Sharkey                    Bundle.setDefusable(extras, true);
774db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                    Call call = mCallIdMapper.getCall(callId);
775db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                    if (call != null) {
776d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn                        call.onConnectionEvent(event, extras);
777db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                    }
778db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                }
779db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn            } finally {
780db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                Binder.restoreCallingIdentity(token);
781db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn                Log.endSession();
782db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn            }
783db82191d1ef7dd4155478071815a56947b31fc11Tyler Gunn        }
784aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
785aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        @Override
786aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        public void onRttInitiationSuccess(String callId, Session.Info sessionInfo)
787aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                throws RemoteException {
788aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
789aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
790aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
791aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        @Override
792aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        public void onRttInitiationFailure(String callId, int reason, Session.Info sessionInfo)
793aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                throws RemoteException {
794aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            Log.startSession(sessionInfo, "CSW.oRIF");
795aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            long token = Binder.clearCallingIdentity();
796aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            try {
797aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                synchronized (mLock) {
798aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                    Call call = mCallIdMapper.getCall(callId);
799aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                    if (call != null) {
800aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                        call.onRttConnectionFailure(reason);
801aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                    }
802aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                }
803aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            } finally {
804aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                Binder.restoreCallingIdentity(token);
805aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                Log.endSession();
806aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            }
807aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
808aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
809aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        @Override
810aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        public void onRttSessionRemotelyTerminated(String callId, Session.Info sessionInfo)
811aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                throws RemoteException {
812aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
813aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
814aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
815aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        @Override
816aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        public void onRemoteRttRequest(String callId, Session.Info sessionInfo)
817aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                throws RemoteException {
818aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            Log.startSession(sessionInfo, "CSW.oRRR");
819aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            long token = Binder.clearCallingIdentity();
820aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            try {
821aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                synchronized (mLock) {
822aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                    Call call = mCallIdMapper.getCall(callId);
823aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                    if (call != null) {
824aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                        call.onRemoteRttRequest();
825aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                    }
826aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                }
827aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            } finally {
828aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                Binder.restoreCallingIdentity(token);
829aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                Log.endSession();
830aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            }
831aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
8323d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    }
8333d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
8343d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    private final Adapter mAdapter = new Adapter();
8356e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    private final CallIdMapper mCallIdMapper = new CallIdMapper(Call::getConnectionId);
836664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
837c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
838512d6350a66b44f1065d6fd2e14ec328449e8119Ihab Awad    private Binder2 mBinder = new Binder2();
839c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    private IConnectionService mServiceInterface;
840905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal    private final ConnectionServiceRepository mConnectionServiceRepository;
84191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
8428de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad    private final CallsManager mCallsManager;
843913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger    private final AppOpsManager mAppOpsManager;
8446192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad
84563aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    /**
846905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal     * Creates a connection service.
847c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon     *
848905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal     * @param componentName The component name of the service with which to bind.
849905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal     * @param connectionServiceRepository Connection service repository.
850b78b27693afbe9736f0a54ec473328955251f885Ihab Awad     * @param phoneAccountRegistrar Phone account registrar
8518de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad     * @param callsManager Calls manager
85291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     * @param context The context.
853105d977687d1d0de7cd9420fc140b01404261df1Evan Charlton     * @param userHandle The {@link UserHandle} to use when binding.
85463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon     */
855c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    ConnectionServiceWrapper(
856b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            ComponentName componentName,
857b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            ConnectionServiceRepository connectionServiceRepository,
85891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            PhoneAccountRegistrar phoneAccountRegistrar,
8598de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad            CallsManager callsManager,
860105d977687d1d0de7cd9420fc140b01404261df1Evan Charlton            Context context,
8618d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad            TelecomSystem.SyncRoot lock,
862105d977687d1d0de7cd9420fc140b01404261df1Evan Charlton            UserHandle userHandle) {
8638d5d9ddc66b55b6906364ab3c0e244dab4d58f13Ihab Awad        super(ConnectionService.SERVICE_INTERFACE, componentName, context, lock, userHandle);
864905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal        mConnectionServiceRepository = connectionServiceRepository;
865b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        phoneAccountRegistrar.addListener(new PhoneAccountRegistrar.Listener() {
866b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            // TODO -- Upon changes to PhoneAccountRegistrar, need to re-wire connections
867b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            // To do this, we must proxy remote ConnectionService objects
868b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        });
86991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        mPhoneAccountRegistrar = phoneAccountRegistrar;
8708de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad        mCallsManager = callsManager;
871913509566d7b4057c8e88f0d94792b0d6aeda5e1Brad Ebinger        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
872c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon    }
873c195e3613af47a49e76821d3f24c05adb71cf920Santos Cordon
874c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    /** See {@link IConnectionService#addConnectionServiceAdapter}. */
875c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
876c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (isServiceValid("addConnectionServiceAdapter")) {
87761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
8783fe8b727b04cb677bc757f030c802cd4e6234db7Sailesh Nepal                logOutgoing("addConnectionServiceAdapter %s", adapter);
879b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.addConnectionServiceAdapter(adapter, Log.getExternalSession());
88061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
88163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
88263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon        }
88363aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
88463aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
8856e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    /** See {@link IConnectionService#removeConnectionServiceAdapter}. */
8866e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    private void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
8876e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        if (isServiceValid("removeConnectionServiceAdapter")) {
8886e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            try {
8896e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                logOutgoing("removeConnectionServiceAdapter %s", adapter);
890b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.removeConnectionServiceAdapter(adapter, Log.getExternalSession());
8916e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            } catch (RemoteException e) {
8926e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            }
8936e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        }
8946e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
8956e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
8966192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad    /**
897664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal     * Creates a new connection for a new outgoing call or to attach to an existing incoming call.
8986192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad     */
899f19000764f6b93dfa15561342cbdd9c1aa1d3e22Brad Ebinger    @VisibleForTesting
900f19000764f6b93dfa15561342cbdd9c1aa1d3e22Brad Ebinger    public void createConnection(final Call call, final CreateConnectionResponse response) {
901664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Log.d(this, "createConnection(%s) via %s.", call, getComponentName());
9026192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        BindCallback callback = new BindCallback() {
9033d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
9043d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void onSuccess() {
905682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                String callId = mCallIdMapper.getCallId(call);
906664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                mPendingResponses.put(callId, response);
907682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
908c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                GatewayInfo gatewayInfo = call.getGatewayInfo();
909b3907b3e79864a3a42d5e7105e5051f7e364fdbaSantos Cordon                Bundle extras = call.getIntentExtras();
910c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                if (gatewayInfo != null && gatewayInfo.getGatewayProviderPackageName() != null &&
911201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen                        gatewayInfo.getOriginalAddress() != null) {
912c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                    extras = (Bundle) extras.clone();
913c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                    extras.putString(
9147cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn                            TelecomManager.GATEWAY_PROVIDER_PACKAGE,
915c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                            gatewayInfo.getGatewayProviderPackageName());
916c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                    extras.putParcelable(
9177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn                            TelecomManager.GATEWAY_ORIGINAL_ADDRESS,
918201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen                            gatewayInfo.getOriginalAddress());
919c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                }
920c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal
92166f26d1745238d6c29b3e0b18fb80cdd57b84676mike dooley                if (call.isIncoming() && mCallsManager.getEmergencyCallHelper()
92266f26d1745238d6c29b3e0b18fb80cdd57b84676mike dooley                        .getLastEmergencyCallTimeMillis() > 0) {
923a2b067eacbd9ee7210cb0887a6b26068990d82ffmike dooley                  // Add the last emergency call time to the connection request for incoming calls
924a2b067eacbd9ee7210cb0887a6b26068990d82ffmike dooley                  if (extras == call.getIntentExtras()) {
925a2b067eacbd9ee7210cb0887a6b26068990d82ffmike dooley                    extras = (Bundle) extras.clone();
926a2b067eacbd9ee7210cb0887a6b26068990d82ffmike dooley                  }
92766f26d1745238d6c29b3e0b18fb80cdd57b84676mike dooley                  extras.putLong(android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS,
92866f26d1745238d6c29b3e0b18fb80cdd57b84676mike dooley                      mCallsManager.getEmergencyCallHelper().getLastEmergencyCallTimeMillis());
92966f26d1745238d6c29b3e0b18fb80cdd57b84676mike dooley                }
93066f26d1745238d6c29b3e0b18fb80cdd57b84676mike dooley
9316f6f1c51c0675a67ef7d7e6ea9264429a4cb269dTyler Gunn                // Call is incoming and added because we're handing over from another; tell CS
9326f6f1c51c0675a67ef7d7e6ea9264429a4cb269dTyler Gunn                // that its expected to handover.
933141ef5805d18b0c8b71d2a50f77837e719672569Tyler Gunn                if (call.isIncoming() && call.getHandoverSourceCall() != null) {
9346f6f1c51c0675a67ef7d7e6ea9264429a4cb269dTyler Gunn                    extras.putBoolean(TelecomManager.EXTRA_IS_HANDOVER, true);
935141ef5805d18b0c8b71d2a50f77837e719672569Tyler Gunn                    extras.putParcelable(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT,
936141ef5805d18b0c8b71d2a50f77837e719672569Tyler Gunn                            call.getHandoverSourceCall().getTargetPhoneAccount());
9376f6f1c51c0675a67ef7d7e6ea9264429a4cb269dTyler Gunn                }
9386f6f1c51c0675a67ef7d7e6ea9264429a4cb269dTyler Gunn
939aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                Log.addEvent(call, LogUtils.Events.START_CONNECTION,
940aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                        Log.piiHandle(call.getHandle()));
941a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn
942dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                ConnectionRequest connectionRequest = new ConnectionRequest.Builder()
943dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .setAccountHandle(call.getTargetPhoneAccount())
944dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .setAddress(call.getHandle())
9456b0b6031da009bd85713aaa223a86d9b9ff83db3Brad Ebinger                        .setExtras(extras)
946dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .setVideoState(call.getVideoState())
947dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .setTelecomCallId(callId)
9482b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn                        // For self-managed incoming calls, if there is another ongoing call Telecom
9492b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn                        // is responsible for showing a UI to ask the user if they'd like to answer
9502b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn                        // this new incoming call.
9512b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn                        .setShouldShowIncomingCallUi(
9522b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn                                !mCallsManager.shouldShowSystemIncomingCallUi(call))
953dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .setRttPipeFromInCall(call.getInCallToCsRttPipeForCs())
954dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .setRttPipeToInCall(call.getCsToInCallRttPipeForCs())
955dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                        .build();
956dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu
957dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                try {
958b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    mServiceInterface.createConnection(
959b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                            call.getConnectionManagerPhoneAccount(),
9606fb37c87836b5245046bd3b14320823ab839a10cIhab Awad                            callId,
961dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu                            connectionRequest,
9623258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu                            call.shouldAttachToExistingConnection(),
963b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                            call.isUnknown(),
964b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                            Log.getExternalSession());
965a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn
966682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon                } catch (RemoteException e) {
967664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                    Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
968fb5560d634aef745466e8869f8acf496447da17bIhab Awad                    mPendingResponses.remove(callId).handleCreateConnectionFailure(
969701dc006ac11625b55d872f1639107b028933895Andrew Lee                            new DisconnectCause(DisconnectCause.ERROR, e.toString()));
9706192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad                }
97163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
9723d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
9733d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            @Override
9743d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon            public void onFailure() {
975905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal                Log.e(this, new Exception(), "Failure to call %s", getComponentName());
976701dc006ac11625b55d872f1639107b028933895Andrew Lee                response.handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.ERROR));
9776192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad            }
9786192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad        };
9796192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad
980165c1ced107a1c3b9b359757d41438f9ca585e78Santos Cordon        mBinder.bind(callback, call);
98163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
98263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon
983a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn    /**
984a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn     * Notifies the {@link ConnectionService} associated with a {@link Call} that the request to
985a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn     * create a connection has been denied or failed.
986a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn     * @param call The call.
987a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn     */
988a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn    void createConnectionFailed(final Call call) {
989a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn        Log.d(this, "createConnectionFailed(%s) via %s.", call, getComponentName());
990a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn        BindCallback callback = new BindCallback() {
991a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn            @Override
992a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn            public void onSuccess() {
993a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                final String callId = mCallIdMapper.getCallId(call);
994a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                // If still bound, tell the connection service create connection has failed.
995a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                if (callId != null && isServiceValid("createConnectionFailed")) {
996a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                    Log.addEvent(call, LogUtils.Events.CREATE_CONNECTION_FAILED,
997a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                            Log.piiHandle(call.getHandle()));
998a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                    try {
999a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                        logOutgoing("createConnectionFailed %s", callId);
1000115c06ee64e209cda99abdc1fbd23fd65aa6da47Tyler Gunn                        mServiceInterface.createConnectionFailed(
1001115c06ee64e209cda99abdc1fbd23fd65aa6da47Tyler Gunn                                call.getConnectionManagerPhoneAccount(),
1002115c06ee64e209cda99abdc1fbd23fd65aa6da47Tyler Gunn                                callId,
1003a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                new ConnectionRequest(
1004a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                        call.getTargetPhoneAccount(),
1005a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                        call.getHandle(),
1006a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                        call.getIntentExtras(),
1007a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                        call.getVideoState(),
1008a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                        callId,
1009a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                        false),
1010a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                call.isIncoming(),
1011a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                                Log.getExternalSession());
1012a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                        call.setDisconnectCause(new DisconnectCause(DisconnectCause.CANCELED));
1013a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                        call.disconnect();
1014a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                    } catch (RemoteException e) {
1015a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                    }
1016a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                }
1017a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn            }
1018a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn
1019a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn            @Override
1020a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn            public void onFailure() {
1021a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                // Binding failed.  Oh no.
1022a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn                Log.w(this, "onFailure - could not bind to CS for call %s", call.getId());
1023a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn            }
1024a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn        };
1025a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn
1026a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn        mBinder.bind(callback, call);
1027a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn    }
1028a90ba73e6ca2e7e3ef88e41477bf595e03f9359fTyler Gunn
1029b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#abort(String, Session.Info)  */
1030e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void abort(Call call) {
1031682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        // Clear out any pending outgoing call data
1032969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1033682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
1034c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        // If still bound, tell the connection service to abort.
1035969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("abort")) {
103628e8ad601cbef0abab1cd6aec8c5a3bc881839c2Ben Gilad            try {
103755a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad                logOutgoing("abort %s", callId);
1038b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.abort(callId, Log.getExternalSession());
103928e8ad601cbef0abab1cd6aec8c5a3bc881839c2Ben Gilad            } catch (RemoteException e) {
104061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            }
104161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
1042682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
1043701dc006ac11625b55d872f1639107b028933895Andrew Lee        removeCall(call, new DisconnectCause(DisconnectCause.LOCAL));
104461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
104561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
1046b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#silence(String, Session.Info) */
10476d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee    void silence(Call call) {
10486d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee        final String callId = mCallIdMapper.getCallId(call);
10496d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee        if (callId != null && isServiceValid("silence")) {
10506d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee            try {
10516d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee                logOutgoing("silence %s", callId);
1052b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.silence(callId, Log.getExternalSession());
10536d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee            } catch (RemoteException e) {
10546d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee            }
10556d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee        }
10566d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee    }
10576d96252436c34cbc2407767f67f2f397f390ad95Bryce Lee
1058b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#hold(String, Session.Info) */
1059e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void hold(Call call) {
1060969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1061969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("hold")) {
1062cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            try {
1063969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("hold %s", callId);
1064b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.hold(callId, Log.getExternalSession());
1065cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            } catch (RemoteException e) {
1066cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            }
1067cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        }
1068cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    }
1069cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
1070b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#unhold(String, Session.Info) */
1071e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void unhold(Call call) {
1072969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1073969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("unhold")) {
1074cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            try {
1075969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("unhold %s", callId);
1076b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.unhold(callId, Log.getExternalSession());
1077cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            } catch (RemoteException e) {
1078cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee            }
1079cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        }
1080cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    }
1081cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
1082b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#onCallAudioStateChanged(String, CallAudioState, Session.Info) */
1083f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu    @VisibleForTesting
1084f62630a57de0d52be2bdbc92a9bf8f305cc0892dHall Liu    public void onCallAudioStateChanged(Call activeCall, CallAudioState audioState) {
1085969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(activeCall);
10862a66f7b906b225413ae33f72e70a75e4f9c883c0Yorke Lee        if (callId != null && isServiceValid("onCallAudioStateChanged")) {
10876aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            try {
10882a66f7b906b225413ae33f72e70a75e4f9c883c0Yorke Lee                logOutgoing("onCallAudioStateChanged %s %s", callId, audioState);
1089b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.onCallAudioStateChanged(callId, audioState,
1090b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                        Log.getExternalSession());
10916aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            } catch (RemoteException e) {
10926aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            }
10936aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal        }
10946aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    }
10956aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal
1096b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#disconnect(String, Session.Info) */
1097e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void disconnect(Call call) {
1098969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1099969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("disconnect")) {
110061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
1101969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("disconnect %s", callId);
1102b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.disconnect(callId, Log.getExternalSession());
110361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
110461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            }
110561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
110661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
110761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
1108b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#answer(String, Session.Info) */
110938931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee    void answer(Call call, int videoState) {
1110969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1111969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("answer")) {
111261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
1113969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("answer %s %d", callId, videoState);
1114467b64fb79f8720958bba6dff84d4827458d33e2Tyler Gunn                if (VideoProfile.isAudioOnly(videoState)) {
1115b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                    mServiceInterface.answer(callId, Log.getExternalSession());
1116041eff6b45ff885e77d2e1b8b9ca9099dd0885d2Tyler Gunn                } else {
1117b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                    mServiceInterface.answerVideo(callId, videoState, Log.getExternalSession());
1118041eff6b45ff885e77d2e1b8b9ca9099dd0885d2Tyler Gunn                }
111961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
112063aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon            }
112163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon        }
112263aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon    }
11235c12c6e00101d16d2db776839a027c62c109dea8Santos Cordon
1124b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#reject(String, Session.Info) */
1125ddd966e7f6b947e345163c442f4c2f9c3d146024Bryce Lee    void reject(Call call, boolean rejectWithMessage, String message) {
1126969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1127969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("reject")) {
112861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            try {
1129969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("reject %s", callId);
1130ddd966e7f6b947e345163c442f4c2f9c3d146024Bryce Lee
1131ddd966e7f6b947e345163c442f4c2f9c3d146024Bryce Lee                if (rejectWithMessage && call.can(
11324b1617a620039fd0d8321028b46c27b486b90763Hall Liu                        Connection.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION)) {
1133b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                    mServiceInterface.rejectWithMessage(callId, message, Log.getExternalSession());
1134ddd966e7f6b947e345163c442f4c2f9c3d146024Bryce Lee                } else {
1135b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                    mServiceInterface.reject(callId, Log.getExternalSession());
1136ddd966e7f6b947e345163c442f4c2f9c3d146024Bryce Lee                }
113761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            } catch (RemoteException e) {
113874549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            }
113974549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        }
114074549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    }
114174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad
1142b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#playDtmfTone(String, char, Session.Info) */
1143e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void playDtmfTone(Call call, char digit) {
1144969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1145969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("playDtmfTone")) {
114674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            try {
1147969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("playDtmfTone %s %c", callId, digit);
1148b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.playDtmfTone(callId, digit, Log.getExternalSession());
114974549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            } catch (RemoteException e) {
115074549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            }
115174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        }
115274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    }
115374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad
1154b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger    /** @see IConnectionService#stopDtmfTone(String, Session.Info) */
1155e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void stopDtmfTone(Call call) {
1156969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1157969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("stopDtmfTone")) {
115874549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            try {
115911623a354be47205bf3bc686ed8fdfc278958983Brad Ebinger                logOutgoing("stopDtmfTone %s", callId);
1160b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.stopDtmfTone(callId, Log.getExternalSession());
116174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad            } catch (RemoteException e) {
11627917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon            }
11637917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon        }
11647917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon    }
11657917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon
1166e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void addCall(Call call) {
1167a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        if (mCallIdMapper.getCallId(call) == null) {
1168a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            mCallIdMapper.addCall(call);
1169a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
11707917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon    }
11717917d38176b6cc432314433d36d7bb46a09f5afcSantos Cordon
11720e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal    /**
1173c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal     * Associates newCall with this connection service by replacing callToReplace.
11740e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal     */
11750e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal    void replaceCall(Call newCall, Call callToReplace) {
1176c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        Preconditions.checkState(callToReplace.getConnectionService() == this);
11770e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal        mCallIdMapper.replaceCall(newCall, callToReplace);
11780e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal    }
11790e5410a58043ce059884fdc8811a280655e5a920Sailesh Nepal
1180e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal    void removeCall(Call call) {
1181701dc006ac11625b55d872f1639107b028933895Andrew Lee        removeCall(call, new DisconnectCause(DisconnectCause.ERROR));
1182fd6ca447a45c47aeb3956964103770475c655a26Santos Cordon    }
1183fd6ca447a45c47aeb3956964103770475c655a26Santos Cordon
1184701dc006ac11625b55d872f1639107b028933895Andrew Lee    void removeCall(String callId, DisconnectCause disconnectCause) {
1185fb5560d634aef745466e8869f8acf496447da17bIhab Awad        CreateConnectionResponse response = mPendingResponses.remove(callId);
1186fb5560d634aef745466e8869f8acf496447da17bIhab Awad        if (response != null) {
1187701dc006ac11625b55d872f1639107b028933895Andrew Lee            response.handleCreateConnectionFailure(disconnectCause);
1188fb5560d634aef745466e8869f8acf496447da17bIhab Awad        }
1189fb5560d634aef745466e8869f8acf496447da17bIhab Awad
1190fb5560d634aef745466e8869f8acf496447da17bIhab Awad        mCallIdMapper.removeCall(callId);
1191fb5560d634aef745466e8869f8acf496447da17bIhab Awad    }
1192fb5560d634aef745466e8869f8acf496447da17bIhab Awad
1193701dc006ac11625b55d872f1639107b028933895Andrew Lee    void removeCall(Call call, DisconnectCause disconnectCause) {
1194664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        CreateConnectionResponse response = mPendingResponses.remove(mCallIdMapper.getCallId(call));
1195664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (response != null) {
1196701dc006ac11625b55d872f1639107b028933895Andrew Lee            response.handleCreateConnectionFailure(disconnectCause);
1197682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        }
1198682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
1199e59bb195972d65a71618af4fe13f1ad982253e16Sailesh Nepal        mCallIdMapper.removeCall(call);
1200adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee    }
1201adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee
1202352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton    void onPostDialContinue(Call call, boolean proceed) {
1203969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1204969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("onPostDialContinue")) {
1205352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton            try {
1206969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("onPostDialContinue %s %b", callId, proceed);
1207b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.onPostDialContinue(callId, proceed, Log.getExternalSession());
1208352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton            } catch (RemoteException ignored) {
1209352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton            }
1210352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton        }
1211352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton    }
1212352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton
12130fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon    void conference(final Call call, Call otherCall) {
1214969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
12150fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon        final String otherCallId = mCallIdMapper.getCallId(otherCall);
12160fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon        if (callId != null && otherCallId != null && isServiceValid("conference")) {
1217a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            try {
12180fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon                logOutgoing("conference %s %s", callId, otherCallId);
1219b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.conference(callId, otherCallId, Log.getExternalSession());
1220a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            } catch (RemoteException ignored) {
1221a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            }
1222a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
1223a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
1224a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
1225a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    void splitFromConference(Call call) {
1226969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        final String callId = mCallIdMapper.getCallId(call);
1227969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner        if (callId != null && isServiceValid("splitFromConference")) {
1228a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            try {
1229969755a2a7ff9416f677dd87d520fce27e629dffJay Shrauner                logOutgoing("splitFromConference %s", callId);
1230b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.splitFromConference(callId, Log.getExternalSession());
1231a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            } catch (RemoteException ignored) {
1232a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            }
1233a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
1234a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
1235a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
12366805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    void mergeConference(Call call) {
12376805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        final String callId = mCallIdMapper.getCallId(call);
12386805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        if (callId != null && isServiceValid("mergeConference")) {
12396805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            try {
12406805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon                logOutgoing("mergeConference %s", callId);
1241b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.mergeConference(callId, Log.getExternalSession());
12426805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            } catch (RemoteException ignored) {
12436805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            }
12446805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        }
12456805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    }
12466805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon
12476805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    void swapConference(Call call) {
12486805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        final String callId = mCallIdMapper.getCallId(call);
12496805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        if (callId != null && isServiceValid("swapConference")) {
12506805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            try {
12516805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon                logOutgoing("swapConference %s", callId);
1252b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.swapConference(callId, Log.getExternalSession());
12536805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            } catch (RemoteException ignored) {
12546805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            }
12556805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        }
12566805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    }
12576805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon
1258d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn    void pullExternalCall(Call call) {
1259d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        final String callId = mCallIdMapper.getCallId(call);
1260d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        if (callId != null && isServiceValid("pullExternalCall")) {
1261d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn            try {
1262d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn                logOutgoing("pullExternalCall %s", callId);
1263b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.pullExternalCall(callId, Log.getExternalSession());
1264d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn            } catch (RemoteException ignored) {
1265d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn            }
1266d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        }
1267d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn    }
1268d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn
1269d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn    void sendCallEvent(Call call, String event, Bundle extras) {
1270d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        final String callId = mCallIdMapper.getCallId(call);
1271d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        if (callId != null && isServiceValid("sendCallEvent")) {
1272d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn            try {
1273d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn                logOutgoing("sendCallEvent %s %s", callId, event);
1274b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.sendCallEvent(callId, event, extras, Log.getExternalSession());
1275d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn            } catch (RemoteException ignored) {
1276d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn            }
1277d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        }
1278d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn    }
1279d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn
1280961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn    void onExtrasChanged(Call call, Bundle extras) {
1281961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        final String callId = mCallIdMapper.getCallId(call);
1282961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        if (callId != null && isServiceValid("onExtrasChanged")) {
1283961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            try {
1284961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                logOutgoing("onExtrasChanged %s %s", callId, extras);
1285b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                mServiceInterface.onExtrasChanged(callId, extras, Log.getExternalSession());
1286961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            } catch (RemoteException ignored) {
1287961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            }
1288961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        }
1289961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn    }
1290961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn
1291aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu    void startRtt(Call call, ParcelFileDescriptor fromInCall, ParcelFileDescriptor toInCall) {
1292aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        final String callId = mCallIdMapper.getCallId(call);
1293aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        if (callId != null && isServiceValid("startRtt")) {
1294aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            try {
1295aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                logOutgoing("startRtt: %s %s %s", callId, fromInCall, toInCall);
1296aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                mServiceInterface.startRtt(callId, fromInCall, toInCall, Log.getExternalSession());
1297aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            } catch (RemoteException ignored) {
1298aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            }
1299aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
1300aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu    }
1301aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
1302aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu    void stopRtt(Call call) {
1303aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        final String callId = mCallIdMapper.getCallId(call);
1304aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        if (callId != null && isServiceValid("stopRtt")) {
1305aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            try {
1306aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                logOutgoing("stopRtt: %s", callId);
1307aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                mServiceInterface.stopRtt(callId, Log.getExternalSession());
1308aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            } catch (RemoteException ignored) {
1309aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            }
1310aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
1311aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu    }
1312aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
1313aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu    void respondToRttRequest(
1314aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            Call call, ParcelFileDescriptor fromInCall, ParcelFileDescriptor toInCall) {
1315aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        final String callId = mCallIdMapper.getCallId(call);
1316aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        if (callId != null && isServiceValid("respondToRttRequest")) {
1317aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            try {
1318aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                logOutgoing("respondToRttRequest: %s %s %s", callId, fromInCall, toInCall);
1319aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                mServiceInterface.respondToRttUpgradeRequest(
1320aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu                        callId, fromInCall, toInCall, Log.getExternalSession());
1321aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            } catch (RemoteException ignored) {
1322aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu            }
1323aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu        }
1324aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu    }
1325aeece4ec4184b76e0ac2e8a012af05638ad866f6Hall Liu
13265c12c6e00101d16d2db776839a027c62c109dea8Santos Cordon    /** {@inheritDoc} */
13273d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    @Override
13283d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    protected void setServiceInterface(IBinder binder) {
13296e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mServiceInterface = IConnectionService.Stub.asInterface(binder);
13306e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        Log.v(this, "Adding Connection Service Adapter.");
13316e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        addConnectionServiceAdapter(mAdapter);
13326e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
13336e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
13346e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    /** {@inheritDoc} */
13356e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    @Override
13366e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected void removeServiceInterface() {
13376e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        Log.v(this, "Removing Connection Service Adapter.");
13386e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        removeConnectionServiceAdapter(mAdapter);
13396e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // We have lost our service connection. Notify the world that this service is done.
13406e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // We must notify the adapter before CallsManager. The adapter will force any pending
13416e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // outgoing calls to try the next service. This needs to happen before CallsManager
13426e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // tries to clean up any calls still associated with this service.
13436e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        handleConnectionServiceDeath();
13446e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mCallsManager.handleConnectionServiceDeath(this);
13456e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mServiceInterface = null;
13465c12c6e00101d16d2db776839a027c62c109dea8Santos Cordon    }
13473d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon
1348fb5560d634aef745466e8869f8acf496447da17bIhab Awad    private void handleCreateConnectionComplete(
1349fb5560d634aef745466e8869f8acf496447da17bIhab Awad            String callId,
1350fb5560d634aef745466e8869f8acf496447da17bIhab Awad            ConnectionRequest request,
1351fb5560d634aef745466e8869f8acf496447da17bIhab Awad            ParcelableConnection connection) {
1352fb5560d634aef745466e8869f8acf496447da17bIhab Awad        // TODO: Note we are not using parameter "request", which is a side effect of our tacit
1353fb5560d634aef745466e8869f8acf496447da17bIhab Awad        // assumption that we have at most one outgoing connection attempt per ConnectionService.
1354fb5560d634aef745466e8869f8acf496447da17bIhab Awad        // This may not continue to be the case.
1355fb5560d634aef745466e8869f8acf496447da17bIhab Awad        if (connection.getState() == Connection.STATE_DISCONNECTED) {
1356fb5560d634aef745466e8869f8acf496447da17bIhab Awad            // A connection that begins in the DISCONNECTED state is an indication of
1357fb5560d634aef745466e8869f8acf496447da17bIhab Awad            // failure to connect; we handle all failures uniformly
1358701dc006ac11625b55d872f1639107b028933895Andrew Lee            removeCall(callId, connection.getDisconnectCause());
1359fb5560d634aef745466e8869f8acf496447da17bIhab Awad        } else {
1360fb5560d634aef745466e8869f8acf496447da17bIhab Awad            // Successful connection
1361fb5560d634aef745466e8869f8acf496447da17bIhab Awad            if (mPendingResponses.containsKey(callId)) {
13628000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad                mPendingResponses.remove(callId)
13638000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad                        .handleCreateConnectionSuccess(mCallIdMapper, connection);
1364fb5560d634aef745466e8869f8acf496447da17bIhab Awad            }
1365fb5560d634aef745466e8869f8acf496447da17bIhab Awad        }
1366fb5560d634aef745466e8869f8acf496447da17bIhab Awad    }
1367fb5560d634aef745466e8869f8acf496447da17bIhab Awad
13683d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon    /**
1369c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal     * Called when the associated connection service dies.
13703d3b4059d7b1fc5a03c4b049b1d436f28ecf84ecSantos Cordon     */
1371c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    private void handleConnectionServiceDeath() {
1372664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (!mPendingResponses.isEmpty()) {
1373664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            CreateConnectionResponse[] responses = mPendingResponses.values().toArray(
1374664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal                    new CreateConnectionResponse[mPendingResponses.values().size()]);
1375664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mPendingResponses.clear();
1376664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            for (int i = 0; i < responses.length; i++) {
1377701dc006ac11625b55d872f1639107b028933895Andrew Lee                responses[i].handleCreateConnectionFailure(
1378f7d32b57ef5e98a56a2e3960ae2f3636002bd55bTyler Gunn                        new DisconnectCause(DisconnectCause.ERROR, "CS_DEATH"));
1379682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            }
1380682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        }
1381a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        mCallIdMapper.clear();
1382a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
138355a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad
138455a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad    private void logIncoming(String msg, Object... params) {
13859b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn        Log.d(this, "ConnectionService -> Telecom[" + mComponentName.flattenToShortString() + "]: "
138646bc3fd58a0ba00e6ff4fb8ba1934ee0baf6bae5Tyler Gunn                + msg, params);
138755a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad    }
138855a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad
138955a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad    private void logOutgoing(String msg, Object... params) {
13909b618b8bd0e3e216ee9d9df96bec0e1f8841aa14Tyler Gunn        Log.d(this, "Telecom -> ConnectionService[" + mComponentName.flattenToShortString() + "]: "
139146bc3fd58a0ba00e6ff4fb8ba1934ee0baf6bae5Tyler Gunn                + msg, params);
139255a3428c6b62e5a84d21f890418cfa9a8494780eIhab Awad    }
13935924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon
1394240656f19c078b4f703d0502ce29114de0d45a50Tony Mak    private void queryRemoteConnectionServices(final UserHandle userHandle,
1395240656f19c078b4f703d0502ce29114de0d45a50Tony Mak            final RemoteServiceCallback callback) {
1396b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        // Only give remote connection services to this connection service if it is listed as
1397b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        // the connection manager.
1398240656f19c078b4f703d0502ce29114de0d45a50Tony Mak        PhoneAccountHandle simCallManager = mPhoneAccountRegistrar.getSimCallManager(userHandle);
1399c17294cfaf9cc649a362117fba544f0b5cb18cdfIhab Awad        Log.d(this, "queryRemoteConnectionServices finds simCallManager = %s", simCallManager);
1400b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        if (simCallManager == null ||
1401b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                !simCallManager.getComponentName().equals(getComponentName())) {
1402b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            noRemoteServices(callback);
1403b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            return;
1404b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        }
1405b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1406b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        // Make a list of ConnectionServices that are listed as being associated with SIM accounts
1407a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner        final Set<ConnectionServiceWrapper> simServices = Collections.newSetFromMap(
1408a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner                new ConcurrentHashMap<ConnectionServiceWrapper, Boolean>(8, 0.9f, 1));
1409240656f19c078b4f703d0502ce29114de0d45a50Tony Mak        for (PhoneAccountHandle handle : mPhoneAccountRegistrar.getSimPhoneAccounts(userHandle)) {
14106a2126477ce3f527ecaec807fe4f40cd13ff02b0Santos Cordon            ConnectionServiceWrapper service = mConnectionServiceRepository.getService(
14116a2126477ce3f527ecaec807fe4f40cd13ff02b0Santos Cordon                    handle.getComponentName(), handle.getUserHandle());
14126a2126477ce3f527ecaec807fe4f40cd13ff02b0Santos Cordon            if (service != null) {
14136a2126477ce3f527ecaec807fe4f40cd13ff02b0Santos Cordon                simServices.add(service);
1414b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            }
1415b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        }
14165924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon
1417b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        final List<ComponentName> simServiceComponentNames = new ArrayList<>();
1418b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        final List<IBinder> simServiceBinders = new ArrayList<>();
14195924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon
1420b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        Log.v(this, "queryRemoteConnectionServices, simServices = %s", simServices);
1421b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1422b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        for (ConnectionServiceWrapper simService : simServices) {
1423b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            if (simService == this) {
1424b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                // Only happens in the unlikely case that a SIM service is also a SIM call manager
1425b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                continue;
14265924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon            }
1427b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1428b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            final ConnectionServiceWrapper currentSimService = simService;
1429b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1430b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            currentSimService.mBinder.bind(new BindCallback() {
1431b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                @Override
1432b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                public void onSuccess() {
1433b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    Log.d(this, "Adding simService %s", currentSimService.getComponentName());
1434b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    simServiceComponentNames.add(currentSimService.getComponentName());
1435b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    simServiceBinders.add(currentSimService.mServiceInterface.asBinder());
1436b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    maybeComplete();
1437b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                }
1438b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1439b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                @Override
1440b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                public void onFailure() {
1441b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    Log.d(this, "Failed simService %s", currentSimService.getComponentName());
1442b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    // We know maybeComplete() will always be a no-op from now on, so go ahead and
1443b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    // signal failure of the entire request
1444b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    noRemoteServices(callback);
1445b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                }
1446b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1447b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                private void maybeComplete() {
1448b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    if (simServiceComponentNames.size() == simServices.size()) {
1449b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                        setRemoteServices(callback, simServiceComponentNames, simServiceBinders);
1450b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    }
1451b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                }
1452165c1ced107a1c3b9b359757d41438f9ca585e78Santos Cordon            }, null);
1453b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        }
1454b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    }
1455b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1456b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    private void setRemoteServices(
1457b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            RemoteServiceCallback callback,
1458b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            List<ComponentName> componentNames,
1459b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            List<IBinder> binders) {
1460b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        try {
1461b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            callback.onResult(componentNames, binders);
1462b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        } catch (RemoteException e) {
1463b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            Log.e(this, e, "Contacting ConnectionService %s",
1464b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                    ConnectionServiceWrapper.this.getComponentName());
1465b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        }
1466b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    }
1467b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
1468b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    private void noRemoteServices(RemoteServiceCallback callback) {
14698de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad        setRemoteServices(callback, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
14705924beafe09bf3fb710ec1bafd59113a12b45adaSantos Cordon    }
147163aeb16a14a94dd44345f6200c7c002e780a15ffSantos Cordon}
1472