152d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon/*
252d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * Copyright (C) 2014 The Android Open Source Project
352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon *
452d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * you may not use this file except in compliance with the License.
652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * You may obtain a copy of the License at
752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon *
852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon *
1052d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * Unless required by applicable law or agreed to in writing, software
1152d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
1252d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * See the License for the specific language governing permissions and
14b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad * limitations under the License.
1552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon */
1652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
17ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnpackage android.telecom;
1852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordonimport android.net.Uri;
206b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordonimport android.os.Bundle;
215d0410fa7c2dead7906780551ba4aa0305021cefIhab Awadimport android.os.IBinder;
22e8dc4bef00e391defbdee0264b2ed955b1117841Santos Cordonimport android.os.IBinder.DeathRecipient;
2352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordonimport android.os.RemoteException;
2452d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
25ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnimport com.android.internal.telecom.IConnectionService;
26ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnimport com.android.internal.telecom.IConnectionServiceAdapter;
27ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnimport com.android.internal.telecom.IVideoProvider;
28ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnimport com.android.internal.telecom.RemoteServiceCallback;
2952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
30b8e85c74e5910a461078704048d67f82b216508cIhab Awadimport java.util.ArrayList;
315d0410fa7c2dead7906780551ba4aa0305021cefIhab Awadimport java.util.HashMap;
325d0410fa7c2dead7906780551ba4aa0305021cefIhab Awadimport java.util.HashSet;
335d0410fa7c2dead7906780551ba4aa0305021cefIhab Awadimport java.util.Map;
345d0410fa7c2dead7906780551ba4aa0305021cefIhab Awadimport java.util.Set;
357c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordonimport java.util.List;
3652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordonimport java.util.UUID;
3752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
3852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon/**
3952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon * Remote connection service which other connection services can use to place calls on their behalf.
40091768c3021d740b7d66846d36405c4d4c76cc56Sailesh Nepal *
41091768c3021d740b7d66846d36405c4d4c76cc56Sailesh Nepal * @hide
4252d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon */
435d0410fa7c2dead7906780551ba4aa0305021cefIhab Awadfinal class RemoteConnectionService {
44480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal
454a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn    // Note: Casting null to avoid ambiguous constructor reference.
46b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private static final RemoteConnection NULL_CONNECTION =
474a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn            new RemoteConnection("NULL", null, (ConnectionRequest) null);
48b8e85c74e5910a461078704048d67f82b216508cIhab Awad
49b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private static final RemoteConference NULL_CONFERENCE =
50b8e85c74e5910a461078704048d67f82b216508cIhab Awad            new RemoteConference("NULL", null);
5152d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
525d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad    private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
53480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal        @Override
546107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad        public void handleCreateConnectionComplete(
55b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                String id,
56b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                ConnectionRequest request,
575d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                ParcelableConnection parcel) {
58b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad            RemoteConnection connection =
59b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                    findConnectionForAction(id, "handleCreateConnectionSuccessful");
605d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
615d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                mPendingConnections.remove(connection);
626107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad                // Unconditionally initialize the connection ...
635c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                connection.setConnectionCapabilities(parcel.getConnectionCapabilities());
64720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                connection.setConnectionProperties(parcel.getConnectionProperties());
652d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                if (parcel.getHandle() != null
662d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                    || parcel.getState() != Connection.STATE_DISCONNECTED) {
672d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                    connection.setAddress(parcel.getHandle(), parcel.getHandlePresentation());
682d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                }
692d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                if (parcel.getCallerDisplayName() != null
702d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                    || parcel.getState() != Connection.STATE_DISCONNECTED) {
712d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                    connection.setCallerDisplayName(
722d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                            parcel.getCallerDisplayName(),
732d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                            parcel.getCallerDisplayNamePresentation());
742d3ced758fa42d8a7cf941998355f655ed0bf0b8Sailesh Nepal                }
7570638f1f364ee6ddf50d159ff913a87230c27f70Sailesh Nepal                // Set state after handle so that the client can identify the connection.
76c2a978dba31f0fc83a7d472e6a78bed165eca610Sailesh Nepal                if (parcel.getState() == Connection.STATE_DISCONNECTED) {
77c2a978dba31f0fc83a7d472e6a78bed165eca610Sailesh Nepal                    connection.setDisconnected(parcel.getDisconnectCause());
78c2a978dba31f0fc83a7d472e6a78bed165eca610Sailesh Nepal                } else {
79c2a978dba31f0fc83a7d472e6a78bed165eca610Sailesh Nepal                    connection.setState(parcel.getState());
80c2a978dba31f0fc83a7d472e6a78bed165eca610Sailesh Nepal                }
81b8e85c74e5910a461078704048d67f82b216508cIhab Awad                List<RemoteConnection> conferenceable = new ArrayList<>();
82b8e85c74e5910a461078704048d67f82b216508cIhab Awad                for (String confId : parcel.getConferenceableConnectionIds()) {
83b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    if (mConnectionById.containsKey(confId)) {
84b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        conferenceable.add(mConnectionById.get(confId));
85b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    }
86b8e85c74e5910a461078704048d67f82b216508cIhab Awad                }
87b8e85c74e5910a461078704048d67f82b216508cIhab Awad                connection.setConferenceableConnections(conferenceable);
88a64627c2d3330f6bee8055b2e51ffaf8a122ef2bIhab Awad                connection.setVideoState(parcel.getVideoState());
896107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad                if (connection.getState() == Connection.STATE_DISCONNECTED) {
906107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad                    // ... then, if it was created in a disconnected state, that indicates
916107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad                    // failure on the providing end, so immediately mark it destroyed
926107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad                    connection.setDestroyed();
936107bab041fb7d851fbf865b7310d294aae970c8Ihab Awad                }
94480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal            }
95480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal        }
962ab88cc313fc4af7fb9436e236cd3a5d1ac58478Sailesh Nepal
972a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
985d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setActive(String callId) {
99b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (mConnectionById.containsKey(callId)) {
100b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConnectionForAction(callId, "setActive")
101b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        .setState(Connection.STATE_ACTIVE);
102b8e85c74e5910a461078704048d67f82b216508cIhab Awad            } else {
103b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConferenceForAction(callId, "setActive")
104b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        .setState(Connection.STATE_ACTIVE);
105b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
10652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
10752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1082a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
1095d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setRinging(String callId) {
1105d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            findConnectionForAction(callId, "setRinging")
111b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                    .setState(Connection.STATE_RINGING);
1125ffbe8b850c2703b64617f0140d051a5412dd861Andrew Lee        }
1135ffbe8b850c2703b64617f0140d051a5412dd861Andrew Lee
1142a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
1155d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setDialing(String callId) {
1165d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            findConnectionForAction(callId, "setDialing")
117b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                    .setState(Connection.STATE_DIALING);
11852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
11952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1202a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
121c96b5e087382a2a530e9c8cf8f2e1f8dbfc439c5Tyler Gunn        public void setPulling(String callId) {
122c96b5e087382a2a530e9c8cf8f2e1f8dbfc439c5Tyler Gunn            findConnectionForAction(callId, "setPulling")
123c96b5e087382a2a530e9c8cf8f2e1f8dbfc439c5Tyler Gunn                    .setState(Connection.STATE_PULLING_CALL);
124c96b5e087382a2a530e9c8cf8f2e1f8dbfc439c5Tyler Gunn        }
125c96b5e087382a2a530e9c8cf8f2e1f8dbfc439c5Tyler Gunn
126c96b5e087382a2a530e9c8cf8f2e1f8dbfc439c5Tyler Gunn        @Override
1277f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee        public void setDisconnected(String callId, DisconnectCause disconnectCause) {
128b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (mConnectionById.containsKey(callId)) {
129b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConnectionForAction(callId, "setDisconnected")
1307f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee                        .setDisconnected(disconnectCause);
131b8e85c74e5910a461078704048d67f82b216508cIhab Awad            } else {
132b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConferenceForAction(callId, "setDisconnected")
1337f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee                        .setDisconnected(disconnectCause);
134b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
13552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
13652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1372a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
1385d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setOnHold(String callId) {
139b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (mConnectionById.containsKey(callId)) {
140b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConnectionForAction(callId, "setOnHold")
141b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        .setState(Connection.STATE_HOLDING);
142b8e85c74e5910a461078704048d67f82b216508cIhab Awad            } else {
143b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConferenceForAction(callId, "setOnHold")
144b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        .setState(Connection.STATE_HOLDING);
145b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
14652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
14752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1482a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
149100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee        public void setRingbackRequested(String callId, boolean ringing) {
150100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee            findConnectionForAction(callId, "setRingbackRequested")
151100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee                    .setRingbackRequested(ringing);
15252d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
15352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1542a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
1555c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad        public void setConnectionCapabilities(String callId, int connectionCapabilities) {
156b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (mConnectionById.containsKey(callId)) {
1575c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                findConnectionForAction(callId, "setConnectionCapabilities")
1585c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                        .setConnectionCapabilities(connectionCapabilities);
159b8e85c74e5910a461078704048d67f82b216508cIhab Awad            } else {
1605c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                findConferenceForAction(callId, "setConnectionCapabilities")
1615c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                        .setConnectionCapabilities(connectionCapabilities);
162b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
16352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
16452d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1652a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
166720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        public void setConnectionProperties(String callId, int connectionProperties) {
167720c664401081ca00e56c7eef12641ae792da530Tyler Gunn            if (mConnectionById.containsKey(callId)) {
168720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                findConnectionForAction(callId, "setConnectionProperties")
169720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                        .setConnectionProperties(connectionProperties);
170720c664401081ca00e56c7eef12641ae792da530Tyler Gunn            } else {
171720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                findConferenceForAction(callId, "setConnectionProperties")
172720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                        .setConnectionProperties(connectionProperties);
173720c664401081ca00e56c7eef12641ae792da530Tyler Gunn            }
174720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        }
175720c664401081ca00e56c7eef12641ae792da530Tyler Gunn
176720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        @Override
1775d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setIsConferenced(String callId, String conferenceCallId) {
178b8e85c74e5910a461078704048d67f82b216508cIhab Awad            // Note: callId should not be null; conferenceCallId may be null
179b8e85c74e5910a461078704048d67f82b216508cIhab Awad            RemoteConnection connection =
180b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    findConnectionForAction(callId, "setIsConferenced");
181b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (connection != NULL_CONNECTION) {
182b8e85c74e5910a461078704048d67f82b216508cIhab Awad                if (conferenceCallId == null) {
183b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    // 'connection' is being split from its conference
184b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    if (connection.getConference() != null) {
185b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        connection.getConference().removeConnection(connection);
186b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    }
187b8e85c74e5910a461078704048d67f82b216508cIhab Awad                } else {
188b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    RemoteConference conference =
189b8e85c74e5910a461078704048d67f82b216508cIhab Awad                            findConferenceForAction(conferenceCallId, "setIsConferenced");
190b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    if (conference != NULL_CONFERENCE) {
191b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        conference.addConnection(connection);
192b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    }
193b8e85c74e5910a461078704048d67f82b216508cIhab Awad                }
194b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
19552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
19652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
1972a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
19817455a3d39350a39eb995897929977d793358365Anthony Lee        public void setConferenceMergeFailed(String callId) {
19917455a3d39350a39eb995897929977d793358365Anthony Lee            // Nothing to do here.
20017455a3d39350a39eb995897929977d793358365Anthony Lee            // The event has already been handled and there is no state to update
20117455a3d39350a39eb995897929977d793358365Anthony Lee            // in the underlying connection or conference objects
20217455a3d39350a39eb995897929977d793358365Anthony Lee        }
20317455a3d39350a39eb995897929977d793358365Anthony Lee
20417455a3d39350a39eb995897929977d793358365Anthony Lee        @Override
205b8e85c74e5910a461078704048d67f82b216508cIhab Awad        public void addConferenceCall(
206b8e85c74e5910a461078704048d67f82b216508cIhab Awad                final String callId,
207b8e85c74e5910a461078704048d67f82b216508cIhab Awad                ParcelableConference parcel) {
208b8e85c74e5910a461078704048d67f82b216508cIhab Awad            RemoteConference conference = new RemoteConference(callId,
209b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    mOutgoingConnectionServiceRpc);
210b8e85c74e5910a461078704048d67f82b216508cIhab Awad
211b8e85c74e5910a461078704048d67f82b216508cIhab Awad            for (String id : parcel.getConnectionIds()) {
212b8e85c74e5910a461078704048d67f82b216508cIhab Awad                RemoteConnection c = mConnectionById.get(id);
213b8e85c74e5910a461078704048d67f82b216508cIhab Awad                if (c != null) {
214b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    conference.addConnection(c);
215b8e85c74e5910a461078704048d67f82b216508cIhab Awad                }
216b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
217b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (conference.getConnections().size() == 0) {
218b8e85c74e5910a461078704048d67f82b216508cIhab Awad                // A conference was created, but none of its connections are ones that have been
219b8e85c74e5910a461078704048d67f82b216508cIhab Awad                // created by, and therefore being tracked by, this remote connection service. It
220b8e85c74e5910a461078704048d67f82b216508cIhab Awad                // is of no interest to us.
2212282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn                Log.d(this, "addConferenceCall - skipping");
222b8e85c74e5910a461078704048d67f82b216508cIhab Awad                return;
223b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
224b8e85c74e5910a461078704048d67f82b216508cIhab Awad
225b8e85c74e5910a461078704048d67f82b216508cIhab Awad            conference.setState(parcel.getState());
2265c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad            conference.setConnectionCapabilities(parcel.getConnectionCapabilities());
22704ce7578607e022e980f69a45bccfa6f84ad6785Tyler Gunn            conference.setConnectionProperties(parcel.getConnectionProperties());
2282282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            conference.putExtras(parcel.getExtras());
229b8e85c74e5910a461078704048d67f82b216508cIhab Awad            mConferenceById.put(callId, conference);
2302282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn
2312282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            // Stash the original connection ID as it exists in the source ConnectionService.
2322282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            // Telecom will use this to avoid adding duplicates later.
2332282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            // See comments on Connection.EXTRA_ORIGINAL_CONNECTION_ID for more information.
2342282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            Bundle newExtras = new Bundle();
2352282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            newExtras.putString(Connection.EXTRA_ORIGINAL_CONNECTION_ID, callId);
2362282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            conference.putExtras(newExtras);
2372282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn
238100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee            conference.registerCallback(new RemoteConference.Callback() {
239b8e85c74e5910a461078704048d67f82b216508cIhab Awad                @Override
240b8e85c74e5910a461078704048d67f82b216508cIhab Awad                public void onDestroyed(RemoteConference c) {
241b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    mConferenceById.remove(callId);
242b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    maybeDisconnectAdapter();
243b8e85c74e5910a461078704048d67f82b216508cIhab Awad                }
244b8e85c74e5910a461078704048d67f82b216508cIhab Awad            });
245b8e85c74e5910a461078704048d67f82b216508cIhab Awad
246b8e85c74e5910a461078704048d67f82b216508cIhab Awad            mOurConnectionServiceImpl.addRemoteConference(conference);
24752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
24852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
2492a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
2505d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void removeCall(String callId) {
251b8e85c74e5910a461078704048d67f82b216508cIhab Awad            if (mConnectionById.containsKey(callId)) {
252b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConnectionForAction(callId, "removeCall")
253b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        .setDestroyed();
254b8e85c74e5910a461078704048d67f82b216508cIhab Awad            } else {
255b8e85c74e5910a461078704048d67f82b216508cIhab Awad                findConferenceForAction(callId, "removeCall")
256b8e85c74e5910a461078704048d67f82b216508cIhab Awad                        .setDestroyed();
257b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
25852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
25952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
2602a46b90222e5c9c73de012382a604a71f9c0c30cSailesh Nepal        @Override
2615d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void onPostDialWait(String callId, String remaining) {
2625d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            findConnectionForAction(callId, "onPostDialWait")
2635d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                    .setPostDialWait(remaining);
26452d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
26552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
26652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        @Override
26727d1c2d148fe377ca0d2744f0f85789a42c8f808Nancy Chen        public void onPostDialChar(String callId, char nextChar) {
26827d1c2d148fe377ca0d2744f0f85789a42c8f808Nancy Chen            findConnectionForAction(callId, "onPostDialChar")
26927d1c2d148fe377ca0d2744f0f85789a42c8f808Nancy Chen                    .onPostDialChar(nextChar);
27027d1c2d148fe377ca0d2744f0f85789a42c8f808Nancy Chen        }
27127d1c2d148fe377ca0d2744f0f85789a42c8f808Nancy Chen
27227d1c2d148fe377ca0d2744f0f85789a42c8f808Nancy Chen        @Override
27352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
2745d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            // Not supported from remote connection service.
27552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
2768d83fa9bbd2ad15299a4419241eb10404e7839beTyler Gunn
2778d83fa9bbd2ad15299a4419241eb10404e7839beTyler Gunn        @Override
278b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad        public void setVideoProvider(String callId, IVideoProvider videoProvider) {
27911aeae5e46541ce40fa26c678a50ba80780aee34Sailesh Nepal            RemoteConnection.VideoProvider remoteVideoProvider = null;
28011aeae5e46541ce40fa26c678a50ba80780aee34Sailesh Nepal            if (videoProvider != null) {
28111aeae5e46541ce40fa26c678a50ba80780aee34Sailesh Nepal                remoteVideoProvider = new RemoteConnection.VideoProvider(videoProvider);
28211aeae5e46541ce40fa26c678a50ba80780aee34Sailesh Nepal            }
283a64627c2d3330f6bee8055b2e51ffaf8a122ef2bIhab Awad            findConnectionForAction(callId, "setVideoProvider")
28411aeae5e46541ce40fa26c678a50ba80780aee34Sailesh Nepal                    .setVideoProvider(remoteVideoProvider);
285480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal        }
286480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal
287480315939d4a321992e0288d19797f30e4561e62Sailesh Nepal        @Override
2885d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setVideoState(String callId, int videoState) {
2895d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            findConnectionForAction(callId, "setVideoState")
2905d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                    .setVideoState(videoState);
2915d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        }
2925d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad
2935d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        @Override
294100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee        public void setIsVoipAudioMode(String callId, boolean isVoip) {
295100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee            findConnectionForAction(callId, "setIsVoipAudioMode")
296100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee                    .setIsVoipAudioMode(isVoip);
297aa07df84f279a87ad6370758c9d792a660f2cebbTyler Gunn        }
298aa07df84f279a87ad6370758c9d792a660f2cebbTyler Gunn
299aa07df84f279a87ad6370758c9d792a660f2cebbTyler Gunn        @Override
3005d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setStatusHints(String callId, StatusHints statusHints) {
3015d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            findConnectionForAction(callId, "setStatusHints")
3025d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                    .setStatusHints(statusHints);
3038d83fa9bbd2ad15299a4419241eb10404e7839beTyler Gunn        }
30433aaae4a07fdcce223fe74d96d751f4bffa6723aSailesh Nepal
30533aaae4a07fdcce223fe74d96d751f4bffa6723aSailesh Nepal        @Override
306100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee        public void setAddress(String callId, Uri address, int presentation) {
307100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee            findConnectionForAction(callId, "setAddress")
308100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee                    .setAddress(address, presentation);
30933aaae4a07fdcce223fe74d96d751f4bffa6723aSailesh Nepal        }
310e7ef59a77d55c9802cc7d919f7dd794bd5fea30eSailesh Nepal
311e7ef59a77d55c9802cc7d919f7dd794bd5fea30eSailesh Nepal        @Override
3125d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void setCallerDisplayName(String callId, String callerDisplayName,
3135d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                int presentation) {
3145d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            findConnectionForAction(callId, "setCallerDisplayName")
3155d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                    .setCallerDisplayName(callerDisplayName, presentation);
316612038642fa9cf1545dbcc8274d313192ce928b5Sailesh Nepal        }
317612038642fa9cf1545dbcc8274d313192ce928b5Sailesh Nepal
318612038642fa9cf1545dbcc8274d313192ce928b5Sailesh Nepal        @Override
3195d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public IBinder asBinder() {
3205d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            throw new UnsupportedOperationException();
3212ab88cc313fc4af7fb9436e236cd3a5d1ac58478Sailesh Nepal        }
3227c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordon
3237c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordon        @Override
3247c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordon        public final void setConferenceableConnections(
3257c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordon                String callId, List<String> conferenceableConnectionIds) {
326b8e85c74e5910a461078704048d67f82b216508cIhab Awad            List<RemoteConnection> conferenceable = new ArrayList<>();
327b8e85c74e5910a461078704048d67f82b216508cIhab Awad            for (String id : conferenceableConnectionIds) {
328b8e85c74e5910a461078704048d67f82b216508cIhab Awad                if (mConnectionById.containsKey(id)) {
329b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    conferenceable.add(mConnectionById.get(id));
330b8e85c74e5910a461078704048d67f82b216508cIhab Awad                }
331b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
3327c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordon
33350e3506533478fa273cbc92c2919470d1889f1edIhab Awad            if (hasConnection(callId)) {
33450e3506533478fa273cbc92c2919470d1889f1edIhab Awad                findConnectionForAction(callId, "setConferenceableConnections")
33550e3506533478fa273cbc92c2919470d1889f1edIhab Awad                        .setConferenceableConnections(conferenceable);
33650e3506533478fa273cbc92c2919470d1889f1edIhab Awad            } else {
33750e3506533478fa273cbc92c2919470d1889f1edIhab Awad                findConferenceForAction(callId, "setConferenceableConnections")
33850e3506533478fa273cbc92c2919470d1889f1edIhab Awad                        .setConferenceableConnections(conferenceable);
33950e3506533478fa273cbc92c2919470d1889f1edIhab Awad            }
3407c7bc7f6917484250974c5da00af9ef756844b0aSantos Cordon        }
3414a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn
3424a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn        @Override
3432282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn        public void addExistingConnection(final String callId, ParcelableConnection connection) {
3442282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            RemoteConnection remoteConnection = new RemoteConnection(callId,
3454a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn                    mOutgoingConnectionServiceRpc, connection);
3462282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            mConnectionById.put(callId, remoteConnection);
3472282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            remoteConnection.registerCallback(new RemoteConnection.Callback() {
3482282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn                @Override
3492282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn                public void onDestroyed(RemoteConnection connection) {
3502282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn                    mConnectionById.remove(callId);
3512282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn                    maybeDisconnectAdapter();
3522282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn                }
3532282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            });
3542282bb97e78ea87ff322ecf12563ab0120af2b28Tyler Gunn            mOurConnectionServiceImpl.addRemoteExistingConnection(remoteConnection);
3554a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn        }
3566b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon
3576b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon        @Override
358dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        public void putExtras(String callId, Bundle extras) {
359dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            if (hasConnection(callId)) {
360dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn                findConnectionForAction(callId, "putExtras").putExtras(extras);
361dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            } else {
362dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn                findConferenceForAction(callId, "putExtras").putExtras(extras);
363dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            }
364dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        }
365dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
366dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        @Override
367dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        public void removeExtras(String callId, List<String> keys) {
368dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            if (hasConnection(callId)) {
369dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn                findConnectionForAction(callId, "removeExtra").removeExtras(keys);
3706b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon            } else {
371dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn                findConferenceForAction(callId, "removeExtra").removeExtras(keys);
3726b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon            }
3736b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon        }
374bd1eb1f105e99d55fe87d758e8eafbe55a221a30Tyler Gunn
375bd1eb1f105e99d55fe87d758e8eafbe55a221a30Tyler Gunn        @Override
376876dbfb4767da4a2ba5459d5b78fb6eb55e4516fTyler Gunn        public void onConnectionEvent(String callId, String event, Bundle extras) {
377bd1eb1f105e99d55fe87d758e8eafbe55a221a30Tyler Gunn            if (mConnectionById.containsKey(callId)) {
378876dbfb4767da4a2ba5459d5b78fb6eb55e4516fTyler Gunn                findConnectionForAction(callId, "onConnectionEvent").onConnectionEvent(event,
379876dbfb4767da4a2ba5459d5b78fb6eb55e4516fTyler Gunn                        extras);
380bd1eb1f105e99d55fe87d758e8eafbe55a221a30Tyler Gunn            }
381bd1eb1f105e99d55fe87d758e8eafbe55a221a30Tyler Gunn        }
38252d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    };
38352d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
3845d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad    private final ConnectionServiceAdapterServant mServant =
3855d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            new ConnectionServiceAdapterServant(mServantDelegate);
3865d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad
3875d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
3885d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        @Override
3895d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        public void binderDied() {
3905d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            for (RemoteConnection c : mConnectionById.values()) {
3915d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                c.setDestroyed();
3925d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            }
393b8e85c74e5910a461078704048d67f82b216508cIhab Awad            for (RemoteConference c : mConferenceById.values()) {
394b8e85c74e5910a461078704048d67f82b216508cIhab Awad                c.setDestroyed();
395b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
3965d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            mConnectionById.clear();
397b8e85c74e5910a461078704048d67f82b216508cIhab Awad            mConferenceById.clear();
3985d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            mPendingConnections.clear();
399b8e85c74e5910a461078704048d67f82b216508cIhab Awad            mOutgoingConnectionServiceRpc.asBinder().unlinkToDeath(mDeathRecipient, 0);
4005d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        }
4015d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad    };
40252d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
403b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private final IConnectionService mOutgoingConnectionServiceRpc;
404b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private final ConnectionService mOurConnectionServiceImpl;
4055d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad    private final Map<String, RemoteConnection> mConnectionById = new HashMap<>();
406b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private final Map<String, RemoteConference> mConferenceById = new HashMap<>();
4075d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad    private final Set<RemoteConnection> mPendingConnections = new HashSet<>();
4085d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad
409b8e85c74e5910a461078704048d67f82b216508cIhab Awad    RemoteConnectionService(
410b8e85c74e5910a461078704048d67f82b216508cIhab Awad            IConnectionService outgoingConnectionServiceRpc,
411b8e85c74e5910a461078704048d67f82b216508cIhab Awad            ConnectionService ourConnectionServiceImpl) throws RemoteException {
412b8e85c74e5910a461078704048d67f82b216508cIhab Awad        mOutgoingConnectionServiceRpc = outgoingConnectionServiceRpc;
413b8e85c74e5910a461078704048d67f82b216508cIhab Awad        mOutgoingConnectionServiceRpc.asBinder().linkToDeath(mDeathRecipient, 0);
414b8e85c74e5910a461078704048d67f82b216508cIhab Awad        mOurConnectionServiceImpl = ourConnectionServiceImpl;
41552d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    }
41652d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
41752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    @Override
41852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    public String toString() {
419b8e85c74e5910a461078704048d67f82b216508cIhab Awad        return "[RemoteCS - " + mOutgoingConnectionServiceRpc.asBinder().toString() + "]";
42052d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    }
42152d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
422f8b69887b438683adee56ad1038d1414cc501ff9Ihab Awad    final RemoteConnection createRemoteConnection(
423f8b69887b438683adee56ad1038d1414cc501ff9Ihab Awad            PhoneAccountHandle connectionManagerPhoneAccount,
424f8b69887b438683adee56ad1038d1414cc501ff9Ihab Awad            ConnectionRequest request,
425f8b69887b438683adee56ad1038d1414cc501ff9Ihab Awad            boolean isIncoming) {
426b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad        final String id = UUID.randomUUID().toString();
4278aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad        final ConnectionRequest newRequest = new ConnectionRequest(
4285d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                request.getAccountHandle(),
429ea38cca14964a5ee658899b0bafbc48017d556cdNancy Chen                request.getAddress(),
4305d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                request.getExtras(),
4315d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                request.getVideoState());
4325d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        try {
4338aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad            if (mConnectionById.isEmpty()) {
434b8e85c74e5910a461078704048d67f82b216508cIhab Awad                mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub());
4358aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad            }
4368aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad            RemoteConnection connection =
437b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    new RemoteConnection(id, mOutgoingConnectionServiceRpc, newRequest);
4388aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad            mPendingConnections.add(connection);
439b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad            mConnectionById.put(id, connection);
440b8e85c74e5910a461078704048d67f82b216508cIhab Awad            mOutgoingConnectionServiceRpc.createConnection(
4415d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                    connectionManagerPhoneAccount,
442b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                    id,
4435d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad                    newRequest,
444c3cf982d18e28fc27126265422f36c5e845808dbYorke Lee                    isIncoming,
445c3cf982d18e28fc27126265422f36c5e845808dbYorke Lee                    false /* isUnknownCall */);
446100e293fa8021caed956597daa4e01cb19be1c33Andrew Lee            connection.registerCallback(new RemoteConnection.Callback() {
4478aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad                @Override
4488aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad                public void onDestroyed(RemoteConnection connection) {
449b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad                    mConnectionById.remove(id);
450b8e85c74e5910a461078704048d67f82b216508cIhab Awad                    maybeDisconnectAdapter();
4518aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad                }
4528aecfedb7b5ac1c909a83f97ef8dad7ca4c68d0fIhab Awad            });
4535d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            return connection;
4545d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        } catch (RemoteException e) {
4557f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee            return RemoteConnection.failure(
4567f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee                    new DisconnectCause(DisconnectCause.ERROR, e.toString()));
45752d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon        }
45852d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    }
45952d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon
46050e3506533478fa273cbc92c2919470d1889f1edIhab Awad    private boolean hasConnection(String callId) {
461879142bf1c6b72670d4aedac82938f00a97acf5bmike dooley        return mConnectionById.containsKey(callId);
46250e3506533478fa273cbc92c2919470d1889f1edIhab Awad    }
46350e3506533478fa273cbc92c2919470d1889f1edIhab Awad
464b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad    private RemoteConnection findConnectionForAction(
465b19a0bcdd8a5020c61a0d697f600fdc943c86f59Ihab Awad            String callId, String action) {
4665d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        if (mConnectionById.containsKey(callId)) {
4675d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad            return mConnectionById.get(callId);
4685d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        }
4695d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        Log.w(this, "%s - Cannot find Connection %s", action, callId);
4705d0410fa7c2dead7906780551ba4aa0305021cefIhab Awad        return NULL_CONNECTION;
47152d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon    }
472b8e85c74e5910a461078704048d67f82b216508cIhab Awad
473b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private RemoteConference findConferenceForAction(
474b8e85c74e5910a461078704048d67f82b216508cIhab Awad            String callId, String action) {
475b8e85c74e5910a461078704048d67f82b216508cIhab Awad        if (mConferenceById.containsKey(callId)) {
476b8e85c74e5910a461078704048d67f82b216508cIhab Awad            return mConferenceById.get(callId);
477b8e85c74e5910a461078704048d67f82b216508cIhab Awad        }
478b8e85c74e5910a461078704048d67f82b216508cIhab Awad        Log.w(this, "%s - Cannot find Conference %s", action, callId);
479b8e85c74e5910a461078704048d67f82b216508cIhab Awad        return NULL_CONFERENCE;
480b8e85c74e5910a461078704048d67f82b216508cIhab Awad    }
481b8e85c74e5910a461078704048d67f82b216508cIhab Awad
482b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private void maybeDisconnectAdapter() {
483b8e85c74e5910a461078704048d67f82b216508cIhab Awad        if (mConnectionById.isEmpty() && mConferenceById.isEmpty()) {
484b8e85c74e5910a461078704048d67f82b216508cIhab Awad            try {
485b8e85c74e5910a461078704048d67f82b216508cIhab Awad                mOutgoingConnectionServiceRpc.removeConnectionServiceAdapter(mServant.getStub());
486b8e85c74e5910a461078704048d67f82b216508cIhab Awad            } catch (RemoteException e) {
487b8e85c74e5910a461078704048d67f82b216508cIhab Awad            }
488b8e85c74e5910a461078704048d67f82b216508cIhab Awad        }
489b8e85c74e5910a461078704048d67f82b216508cIhab Awad    }
49052d8a15e146e682319380322f94ceb6d93fa1a97Santos Cordon}
491