ImsExternalCallTracker.java revision da8286bfe1baf68d81a778031d05c3d13fa03f7c
1fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn/* 2fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Copyright (C) 2016 The Android Open Source Project 3fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 4fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Licensed under the Apache License, Version 2.0 (the "License"); 5fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * you may not use this file except in compliance with the License. 6fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * You may obtain a copy of the License at 7fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 8fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * http://www.apache.org/licenses/LICENSE-2.0 9fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 10fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Unless required by applicable law or agreed to in writing, software 11fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * distributed under the License is distributed on an "AS IS" BASIS, 12fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * See the License for the specific language governing permissions and 14fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * limitations under the License 15fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 16fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 17fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnpackage com.android.internal.telephony.imsphone; 18fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 1993da8529345711fd1a5617f3c8b15c0921eececbTyler Gunnimport com.android.ims.ImsCallProfile; 20fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.ims.ImsExternalCallState; 2193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunnimport com.android.ims.ImsExternalCallStateListener; 22fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.internal.telephony.Call; 23fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.internal.telephony.Connection; 24fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.internal.telephony.Phone; 25fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 26fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.os.Bundle; 27fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.telecom.PhoneAccountHandle; 28fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.util.ArrayMap; 29fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.util.Log; 30fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 31fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.ArrayList; 32fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.Iterator; 33fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.List; 34fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.Map; 35fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 36fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn/** 37fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Responsible for tracking external calls known to the system. 38fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 39fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnpublic class ImsExternalCallTracker { 40fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 4193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn /** 4293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn * Implements the {@link ImsExternalCallStateListener}, which is responsible for receiving 4393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn * external call state updates from the IMS framework. 4493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn */ 4593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public class ExternalCallStateListener extends ImsExternalCallStateListener { 4693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn @Override 4793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallState) { 4893da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn refreshExternalCallState(externalCallState); 4993da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 5093da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 5193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 5293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn /** 5393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn * Receives callbacks from {@link ImsExternalConnection}s when a call pull has been initiated. 5493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn */ 5593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public class ExternalConnectionListener implements ImsExternalConnection.Listener { 5693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn @Override 5793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public void onPullExternalCall(ImsExternalConnection connection) { 5893da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn Log.d(TAG, "onPullExternalCall: connection = " + connection); 5993da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn mCallPuller.pullExternalCall(connection.getAddress(), connection.getVideoState()); 6093da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 6193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 6293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 63fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public final static String TAG = "ImsExternalCallTracker"; 64fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 65fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 66fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Extra key used when informing telecom of a new external call using the 67fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * {@link android.telecom.TelecomManager#addNewUnknownCall(PhoneAccountHandle, Bundle)} API. 68fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Used to ensure that when Telecom requests the {@link android.telecom.ConnectionService} to 69fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * create the connection for the unknown call that we can determine which 70fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * {@link ImsExternalConnection} in {@link #mExternalConnections} is the one being requested. 71fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 72fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public final static String EXTRA_IMS_EXTERNAL_CALL_ID = 73fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn "android.telephony.ImsExternalCallTracker.extra.EXTERNAL_CALL_ID"; 74fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 75fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 76fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Contains a list of the external connections known by the ImsPhoneCallTracker. These are 77fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * connections which originated from a dialog event package and reside on another device. 78fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Used in multi-endpoint (VoLTE for internet connected endpoints) scenarios. 79fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 80fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private Map<Integer, ImsExternalConnection> mExternalConnections = 8193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn new ArrayMap<>(); 8293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ImsPhone mPhone; 8393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ExternalCallStateListener mExternalCallStateListener; 8493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ExternalConnectionListener mExternalConnectionListener = 8593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn new ExternalConnectionListener(); 8693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ImsPullCall mCallPuller; 8793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 8893da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public ImsExternalCallTracker(ImsPhone phone, ImsPullCall callPuller) { 89fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mPhone = phone; 9093da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn mExternalCallStateListener = new ExternalCallStateListener(); 9193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn mCallPuller = callPuller; 9293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 9393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 9493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public ExternalCallStateListener getExternalCallStateListener() { 9593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn return mExternalCallStateListener; 96fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 97fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 98fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 99fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Called when the IMS stack receives a new dialog event package. Triggers the creation and 100fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * update of {@link ImsExternalConnection}s to represent the dialogs in the dialog event 101fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * package data. 102fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 103fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param externalCallStates the {@link ImsExternalCallState} information for the dialog event 104fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * package. 105fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 106fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public void refreshExternalCallState(List<ImsExternalCallState> externalCallStates) { 107da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn Log.d(TAG, "refreshExternalCallState"); 108fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 109fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Check to see if any call Ids are no longer present in the external call state. If they 110fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // are, the calls are terminated and should be removed. 111fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Iterator<Map.Entry<Integer, ImsExternalConnection>> connectionIterator = 112fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mExternalConnections.entrySet().iterator(); 113fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn boolean wasCallRemoved = false; 114fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn while (connectionIterator.hasNext()) { 115fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Map.Entry<Integer, ImsExternalConnection> entry = connectionIterator.next(); 116fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn int callId = entry.getKey().intValue(); 117fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 118fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (!containsCallId(externalCallStates, callId)) { 119fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn ImsExternalConnection externalConnection = entry.getValue(); 120fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn externalConnection.setTerminated(); 12193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn externalConnection.removeListener(mExternalConnectionListener); 122fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connectionIterator.remove(); 123fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn wasCallRemoved = true; 124fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 125fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 126fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // If one or more calls were removed, trigger a notification that will cause the 127fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // TelephonyConnection instancse to refresh their state with Telecom. 128fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (wasCallRemoved) { 129fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mPhone.notifyPreciseCallStateChanged(); 130fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 131fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 132fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Check for new calls, and updates to existing ones. 133da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (externalCallStates != null && !externalCallStates.isEmpty()) { 134da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn for (ImsExternalCallState callState : externalCallStates) { 135da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (!mExternalConnections.containsKey(callState.getCallId())) { 136da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn Log.d(TAG, "refreshExternalCallState: got = " + callState); 137da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn // If there is a new entry and it is already terminated, don't bother adding it to 138da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn // telecom. 139da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (callState.getCallState() != ImsExternalCallState.CALL_STATE_CONFIRMED) { 140da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn continue; 141da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn } 142da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn createExternalConnection(callState); 143da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn } else { 144da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn updateExistingConnection(mExternalConnections.get(callState.getCallId()), 145da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn callState); 146fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 147fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 148fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 149fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 150fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 151fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 152fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Finds an external connection given a call Id. 153fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 154fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param callId The call Id. 155fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @return The {@link Connection}, or {@code null} if no match found. 156fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 157fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public Connection getConnectionById(int callId) { 158fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn return mExternalConnections.get(callId); 159fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 160fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 161fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 162fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Given an {@link ImsExternalCallState} instance obtained from a dialog event package, 163fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * creates a new instance of {@link ImsExternalConnection} to represent the connection, and 164fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * initiates the addition of the new call to Telecom as an unknown call. 165fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 166fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param state External call state from a dialog event package. 167fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 168fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private void createExternalConnection(ImsExternalCallState state) { 169fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Log.i(TAG, "createExternalConnection"); 170fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 171fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn ImsExternalConnection connection = new ImsExternalConnection(mPhone, 172fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn state.getCallId(), /* Dialog event package call id */ 173fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn state.getAddress().getSchemeSpecificPart() /* phone number */, 174fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn state.isCallPullable()); 17593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.setVideoState(ImsCallProfile.getVideoStateFromCallType(state.getCallType())); 17693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.addListener(mExternalConnectionListener); 177fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 178fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Add to list of tracked connections. 179fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mExternalConnections.put(connection.getCallId(), connection); 180fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 181fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Note: The notification of unknown connection is ultimately handled by 182fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // PstnIncomingCallNotifier#addNewUnknownCall. That method will ensure that an extra is set 183fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // containing the ImsExternalConnection#mCallId so that we have a means of reconciling which 184fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // unknown call was added. 185fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mPhone.notifyUnknownConnection(connection); 186fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 187fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 188fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 189fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Given an existing {@link ImsExternalConnection}, applies any changes found found in a 190fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * {@link ImsExternalCallState} instance received from a dialog event package to the connection. 191fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 192fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param connection The connection to apply changes to. 193fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param state The new dialog state for the connection. 194fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 195fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private void updateExistingConnection(ImsExternalConnection connection, 196fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn ImsExternalCallState state) { 197fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Call.State existingState = connection.getState(); 198fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Call.State newState = state.getCallState() == ImsExternalCallState.CALL_STATE_CONFIRMED ? 199fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Call.State.ACTIVE : Call.State.DISCONNECTED; 200fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 201fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (existingState != newState) { 202fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (newState == Call.State.ACTIVE) { 203fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connection.setActive(); 204fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } else { 205fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connection.setTerminated(); 20693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.removeListener(mExternalConnectionListener); 207fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mExternalConnections.remove(connection); 208fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mPhone.notifyPreciseCallStateChanged(); 209fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 210fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 211fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 212fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connection.setIsPullable(state.isCallPullable()); 21393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 21493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn int newVideoState = ImsCallProfile.getVideoStateFromCallType(state.getCallType()); 21593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn if (newVideoState != connection.getVideoState()) { 21693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.setVideoState(newVideoState); 21793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 218fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 219fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 220fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 221fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Determines if a list of call states obtained from a dialog event package contacts an existing 222fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * call Id. 223fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 224fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param externalCallStates The dialog event package state information. 225fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param callId The call Id. 226fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @return {@code true} if the state information contains the call Id, {@code false} otherwise. 227fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 228fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private boolean containsCallId(List<ImsExternalCallState> externalCallStates, int callId) { 229da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (externalCallStates == null) { 230da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn return false; 231da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn } 232da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn 233fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn for (ImsExternalCallState state : externalCallStates) { 234fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (state.getCallId() == callId) { 235fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn return true; 236fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 237fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 238fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 239fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn return false; 240fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 241fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn} 242