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; 2267f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunnimport com.android.internal.annotations.VisibleForTesting; 23fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.internal.telephony.Call; 24fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.internal.telephony.Connection; 25fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport com.android.internal.telephony.Phone; 2691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnimport com.android.internal.telephony.PhoneConstants; 27fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 2891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnimport android.os.AsyncResult; 29fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.os.Bundle; 3091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnimport android.os.Handler; 3191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnimport android.os.Message; 32fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.telecom.PhoneAccountHandle; 3391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnimport android.telecom.VideoProfile; 3491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnimport android.telephony.TelephonyManager; 35fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.util.ArrayMap; 36fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport android.util.Log; 37fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 38fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.Iterator; 39fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.List; 40fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunnimport java.util.Map; 41fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 42fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn/** 43fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Responsible for tracking external calls known to the system. 44fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 4591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunnpublic class ImsExternalCallTracker implements ImsPhoneCallTracker.PhoneStateListener { 46fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 4793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn /** 4867f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * Interface implemented by modules which are capable of notifying interested parties of new 4967f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * unknown connections, and changes to call state. 5067f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * This is used to break the dependency between {@link ImsExternalCallTracker} and 5167f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * {@link ImsPhone}. 5267f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * 5367f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * @hide 5467f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn */ 5567f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn public static interface ImsCallNotify { 5667f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn /** 5767f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * Notifies that an unknown connection has been added. 5867f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * @param c The new unknown connection. 5967f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn */ 6067f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn void notifyUnknownConnection(Connection c); 6167f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn 6267f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn /** 6367f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn * Notifies of a change to call state. 6467f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn */ 6567f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn void notifyPreciseCallStateChanged(); 6667f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn } 6767f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn 6867f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn 6967f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn /** 7093da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn * Implements the {@link ImsExternalCallStateListener}, which is responsible for receiving 7193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn * external call state updates from the IMS framework. 7293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn */ 7393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public class ExternalCallStateListener extends ImsExternalCallStateListener { 7493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn @Override 7593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallState) { 7693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn refreshExternalCallState(externalCallState); 7793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 7893da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 7993da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 8093da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn /** 8193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn * Receives callbacks from {@link ImsExternalConnection}s when a call pull has been initiated. 8293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn */ 8393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public class ExternalConnectionListener implements ImsExternalConnection.Listener { 8493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn @Override 8593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public void onPullExternalCall(ImsExternalConnection connection) { 8693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn Log.d(TAG, "onPullExternalCall: connection = " + connection); 8791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn if (mCallPuller == null) { 8891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.e(TAG, "onPullExternalCall : No call puller defined"); 8991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn return; 9091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 913de018282cd7dae66d4dfff41303e81419d2004dTyler Gunn mCallPuller.pullExternalCall(connection.getAddress(), connection.getVideoState(), 923de018282cd7dae66d4dfff41303e81419d2004dTyler Gunn connection.getCallId()); 9393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 9493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 9593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 96fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public final static String TAG = "ImsExternalCallTracker"; 97fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 9891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private static final int EVENT_VIDEO_CAPABILITIES_CHANGED = 1; 9991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 100fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 101fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Extra key used when informing telecom of a new external call using the 102fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * {@link android.telecom.TelecomManager#addNewUnknownCall(PhoneAccountHandle, Bundle)} API. 103fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Used to ensure that when Telecom requests the {@link android.telecom.ConnectionService} to 104fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * create the connection for the unknown call that we can determine which 105fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * {@link ImsExternalConnection} in {@link #mExternalConnections} is the one being requested. 106fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 107fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public final static String EXTRA_IMS_EXTERNAL_CALL_ID = 108fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn "android.telephony.ImsExternalCallTracker.extra.EXTERNAL_CALL_ID"; 109fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 110fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 11191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Contains a list of the external connections known by the ImsExternalCallTracker. These are 112fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * connections which originated from a dialog event package and reside on another device. 113fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Used in multi-endpoint (VoLTE for internet connected endpoints) scenarios. 114fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 115fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private Map<Integer, ImsExternalConnection> mExternalConnections = 11693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn new ArrayMap<>(); 11791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 11891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 11991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Tracks whether each external connection tracked in 12091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * {@link #mExternalConnections} can be pulled, as reported by the latest dialog event package 12191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * received from the network. We need to know this because the pull state of a call can be 12291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * overridden based on the following factors: 12391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * 1) An external video call cannot be pulled if the current device does not have video 12491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * capability. 12591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * 2) If the device has any active or held calls locally, no external calls may be pulled to 12691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * the local device. 12791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 12891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private Map<Integer, Boolean> mExternalCallPullableState = new ArrayMap<>(); 12993da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ImsPhone mPhone; 13067f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn private final ImsCallNotify mCallStateNotifier; 13193da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ExternalCallStateListener mExternalCallStateListener; 13293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn private final ExternalConnectionListener mExternalConnectionListener = 13393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn new ExternalConnectionListener(); 13491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private ImsPullCall mCallPuller; 13591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private boolean mIsVideoCapable; 13691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private boolean mHasActiveCalls; 13791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 13891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private final Handler mHandler = new Handler() { 13991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn @Override 14091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn public void handleMessage(Message msg) { 14191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn switch (msg.what) { 14291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn case EVENT_VIDEO_CAPABILITIES_CHANGED: 14391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn handleVideoCapabilitiesChanged((AsyncResult) msg.obj); 14491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn break; 14591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn default: 14691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn break; 14791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 14891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 14991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn }; 15093da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 15167f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn @VisibleForTesting 15267f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn public ImsExternalCallTracker(ImsPhone phone, ImsPullCall callPuller, 15367f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn ImsCallNotify callNotifier) { 15467f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn 15567f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mPhone = phone; 15667f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mCallStateNotifier = callNotifier; 15767f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mExternalCallStateListener = new ExternalCallStateListener(); 15867f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mCallPuller = callPuller; 15967f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn } 16091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 16191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn public ImsExternalCallTracker(ImsPhone phone) { 162fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mPhone = phone; 16367f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mCallStateNotifier = new ImsCallNotify() { 16467f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn @Override 16567f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn public void notifyUnknownConnection(Connection c) { 16667f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mPhone.notifyUnknownConnection(c); 16767f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn } 16867f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn 16967f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn @Override 17067f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn public void notifyPreciseCallStateChanged() { 17167f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mPhone.notifyPreciseCallStateChanged(); 17267f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn } 17367f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn }; 17493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn mExternalCallStateListener = new ExternalCallStateListener(); 17591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn registerForNotifications(); 17691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 17791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 17891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 17991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Performs any cleanup required before the ImsExternalCallTracker is destroyed. 18091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 18191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn public void tearDown() { 18291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn unregisterForNotifications(); 18391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 18491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 18591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 18691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Sets the implementation of {@link ImsPullCall} which is responsible for pulling calls. 18791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * 18891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @param callPuller The pull call implementation. 18991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 19091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn public void setCallPuller(ImsPullCall callPuller) { 19191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mCallPuller = callPuller; 19293da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 19393da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn 19493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn public ExternalCallStateListener getExternalCallStateListener() { 19593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn return mExternalCallStateListener; 196fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 197fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 198fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 19991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Handles changes to the phone state as notified by the {@link ImsPhoneCallTracker}. 20091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * 20191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @param oldState The previous phone state. 20291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @param newState The new phone state. 20391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 20491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn @Override 20591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn public void onPhoneStateChanged(PhoneConstants.State oldState, PhoneConstants.State newState) { 20691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mHasActiveCalls = newState != PhoneConstants.State.IDLE; 20791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.i(TAG, "onPhoneStateChanged : hasActiveCalls = " + mHasActiveCalls); 20891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 20991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn refreshCallPullState(); 21091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 21191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 21291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 21391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Registers for video capability changes. 21491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 21591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private void registerForNotifications() { 21691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn if (mPhone != null) { 21791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.d(TAG, "Registering: " + mPhone); 21891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mPhone.getDefaultPhone().registerForVideoCapabilityChanged(mHandler, 21991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn EVENT_VIDEO_CAPABILITIES_CHANGED, null); 22091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 22191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 22291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 22391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 22491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Unregisters for video capability changes. 22591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 22691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private void unregisterForNotifications() { 22791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn if (mPhone != null) { 22891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.d(TAG, "Unregistering: " + mPhone); 22991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mPhone.unregisterForVideoCapabilityChanged(mHandler); 23091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 23191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 23291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 23391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 23491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 235fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Called when the IMS stack receives a new dialog event package. Triggers the creation and 236fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * update of {@link ImsExternalConnection}s to represent the dialogs in the dialog event 237fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * package data. 238fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 239fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param externalCallStates the {@link ImsExternalCallState} information for the dialog event 240fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * package. 241fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 242fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public void refreshExternalCallState(List<ImsExternalCallState> externalCallStates) { 243da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn Log.d(TAG, "refreshExternalCallState"); 244fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 245fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Check to see if any call Ids are no longer present in the external call state. If they 246fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // are, the calls are terminated and should be removed. 247fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Iterator<Map.Entry<Integer, ImsExternalConnection>> connectionIterator = 248fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mExternalConnections.entrySet().iterator(); 249fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn boolean wasCallRemoved = false; 250fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn while (connectionIterator.hasNext()) { 251fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Map.Entry<Integer, ImsExternalConnection> entry = connectionIterator.next(); 252fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn int callId = entry.getKey().intValue(); 253fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 254fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (!containsCallId(externalCallStates, callId)) { 255fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn ImsExternalConnection externalConnection = entry.getValue(); 256fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn externalConnection.setTerminated(); 25793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn externalConnection.removeListener(mExternalConnectionListener); 258fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connectionIterator.remove(); 259fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn wasCallRemoved = true; 260fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 261fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 262fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // If one or more calls were removed, trigger a notification that will cause the 263fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // TelephonyConnection instancse to refresh their state with Telecom. 264fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (wasCallRemoved) { 26567f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mCallStateNotifier.notifyPreciseCallStateChanged(); 266fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 267fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 268fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Check for new calls, and updates to existing ones. 269da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (externalCallStates != null && !externalCallStates.isEmpty()) { 270da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn for (ImsExternalCallState callState : externalCallStates) { 271da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (!mExternalConnections.containsKey(callState.getCallId())) { 272da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn Log.d(TAG, "refreshExternalCallState: got = " + callState); 273da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn // If there is a new entry and it is already terminated, don't bother adding it to 274da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn // telecom. 275da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (callState.getCallState() != ImsExternalCallState.CALL_STATE_CONFIRMED) { 276da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn continue; 277da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn } 278da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn createExternalConnection(callState); 279da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn } else { 280da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn updateExistingConnection(mExternalConnections.get(callState.getCallId()), 281da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn callState); 282fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 283fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 284fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 285fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 286fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 287fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 288fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Finds an external connection given a call Id. 289fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 290fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param callId The call Id. 291fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @return The {@link Connection}, or {@code null} if no match found. 292fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 293fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn public Connection getConnectionById(int callId) { 294fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn return mExternalConnections.get(callId); 295fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 296fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 297fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 298fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Given an {@link ImsExternalCallState} instance obtained from a dialog event package, 299fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * creates a new instance of {@link ImsExternalConnection} to represent the connection, and 300fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * initiates the addition of the new call to Telecom as an unknown call. 301fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 302fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param state External call state from a dialog event package. 303fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 304fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private void createExternalConnection(ImsExternalCallState state) { 30591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.i(TAG, "createExternalConnection : state = " + state); 30691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 30791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn int videoState = ImsCallProfile.getVideoStateFromCallType(state.getCallType()); 308fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 30991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn boolean isCallPullPermitted = isCallPullPermitted(state.isCallPullable(), videoState); 310fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn ImsExternalConnection connection = new ImsExternalConnection(mPhone, 311fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn state.getCallId(), /* Dialog event package call id */ 3121c23d391a314ffdb71874b06e9a0e54607208832Tyler Gunn state.getAddress() /* phone number */, 31391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn isCallPullPermitted); 31491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn connection.setVideoState(videoState); 31593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.addListener(mExternalConnectionListener); 316fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 31791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.d(TAG, 31891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn "createExternalConnection - pullable state : externalCallId = " 31991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + connection.getCallId() 32091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; isPullable = " + isCallPullPermitted 32191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; networkPullable = " + state.isCallPullable() 32291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; isVideo = " + VideoProfile.isVideo(videoState) 32391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; videoEnabled = " + mIsVideoCapable 32491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; hasActiveCalls = " + mHasActiveCalls); 32591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 326fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Add to list of tracked connections. 327fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn mExternalConnections.put(connection.getCallId(), connection); 328814442c3754ef76d896247aa72cf0b050c6c0f29Tyler Gunn mExternalCallPullableState.put(connection.getCallId(), state.isCallPullable()); 329fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 330fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // Note: The notification of unknown connection is ultimately handled by 331fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // PstnIncomingCallNotifier#addNewUnknownCall. That method will ensure that an extra is set 332fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // containing the ImsExternalConnection#mCallId so that we have a means of reconciling which 333fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn // unknown call was added. 33467f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mCallStateNotifier.notifyUnknownConnection(connection); 335fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 336fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 337fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 338fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Given an existing {@link ImsExternalConnection}, applies any changes found found in a 339fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * {@link ImsExternalCallState} instance received from a dialog event package to the connection. 340fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 341fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param connection The connection to apply changes to. 342fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param state The new dialog state for the connection. 343fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 344fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private void updateExistingConnection(ImsExternalConnection connection, 345fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn ImsExternalCallState state) { 34691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 34791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.i(TAG, "updateExistingConnection : state = " + state); 348fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Call.State existingState = connection.getState(); 349fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Call.State newState = state.getCallState() == ImsExternalCallState.CALL_STATE_CONFIRMED ? 350fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn Call.State.ACTIVE : Call.State.DISCONNECTED; 351fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 352fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (existingState != newState) { 353fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (newState == Call.State.ACTIVE) { 354fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connection.setActive(); 355fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } else { 356fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn connection.setTerminated(); 35793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.removeListener(mExternalConnectionListener); 35891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mExternalConnections.remove(connection.getCallId()); 35991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mExternalCallPullableState.remove(connection.getCallId()); 36067f3535dbfa1e4ca1ed846dd649015e8bd1f7328Tyler Gunn mCallStateNotifier.notifyPreciseCallStateChanged(); 361fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 362fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 363fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 36493da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn int newVideoState = ImsCallProfile.getVideoStateFromCallType(state.getCallType()); 36593da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn if (newVideoState != connection.getVideoState()) { 36693da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn connection.setVideoState(newVideoState); 36793da8529345711fd1a5617f3c8b15c0921eececbTyler Gunn } 36891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 369814442c3754ef76d896247aa72cf0b050c6c0f29Tyler Gunn mExternalCallPullableState.put(state.getCallId(), state.isCallPullable()); 37091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn boolean isCallPullPermitted = isCallPullPermitted(state.isCallPullable(), newVideoState); 37191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.d(TAG, 372814442c3754ef76d896247aa72cf0b050c6c0f29Tyler Gunn "updateExistingConnection - pullable state : externalCallId = " + connection 373814442c3754ef76d896247aa72cf0b050c6c0f29Tyler Gunn .getCallId() 37491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; isPullable = " + isCallPullPermitted 37591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; networkPullable = " + state.isCallPullable() 37691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; isVideo = " 37791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + VideoProfile.isVideo(connection.getVideoState()) 37891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; videoEnabled = " + mIsVideoCapable 37991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; hasActiveCalls = " + mHasActiveCalls); 38091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 38191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn connection.setIsPullable(isCallPullPermitted); 38291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 38391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 38491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 38591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Update whether the external calls known can be pulled. Combines the last known network 38691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * pullable state with local device conditions to determine if each call can be pulled. 38791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 38891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private void refreshCallPullState() { 38991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.d(TAG, "refreshCallPullState"); 39091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 39191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn for (ImsExternalConnection imsExternalConnection : mExternalConnections.values()) { 39291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn boolean isNetworkPullable = 39391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mExternalCallPullableState.get(imsExternalConnection.getCallId()) 39491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn .booleanValue(); 39591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn boolean isCallPullPermitted = 39691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn isCallPullPermitted(isNetworkPullable, imsExternalConnection.getVideoState()); 39791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.d(TAG, 39891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn "refreshCallPullState : externalCallId = " + imsExternalConnection.getCallId() 39991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; isPullable = " + isCallPullPermitted 40091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; networkPullable = " + isNetworkPullable 40191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; isVideo = " 40291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + VideoProfile.isVideo(imsExternalConnection.getVideoState()) 40391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; videoEnabled = " + mIsVideoCapable 40491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn + " ; hasActiveCalls = " + mHasActiveCalls); 40591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn imsExternalConnection.setIsPullable(isCallPullPermitted); 40691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 407fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 408fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 409fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn /** 410fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * Determines if a list of call states obtained from a dialog event package contacts an existing 411fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * call Id. 412fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * 413fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param externalCallStates The dialog event package state information. 414fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @param callId The call Id. 415fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn * @return {@code true} if the state information contains the call Id, {@code false} otherwise. 416fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn */ 417fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn private boolean containsCallId(List<ImsExternalCallState> externalCallStates, int callId) { 418da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn if (externalCallStates == null) { 419da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn return false; 420da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn } 421da8286bfe1baf68d81a778031d05c3d13fa03f7cTyler Gunn 422fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn for (ImsExternalCallState state : externalCallStates) { 423fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn if (state.getCallId() == callId) { 424fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn return true; 425fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 426fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 427fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn 428fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn return false; 429fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn } 43091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 43191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 43291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Handles a change to the video capabilities reported by 43391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * {@link Phone#notifyForVideoCapabilityChanged(boolean)}. 43491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * 43591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @param ar The AsyncResult containing the new video capability of the device. 43691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 43791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private void handleVideoCapabilitiesChanged(AsyncResult ar) { 43891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn mIsVideoCapable = (Boolean) ar.result; 43991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn Log.i(TAG, "handleVideoCapabilitiesChanged : isVideoCapable = " + mIsVideoCapable); 44091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 44191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn // Refresh pullable state if video capability changed. 44291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn refreshCallPullState(); 44391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 44491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 44591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn /** 44691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * Determines whether an external call can be pulled based on the pullability state enforced 44791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * by the network, as well as local device rules. 44891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * 44991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @param isNetworkPullable {@code true} if the network indicates the call can be pulled, 45091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * {@code false} otherwise. 45191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @param videoState the VideoState of the external call. 45291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn * @return {@code true} if the external call can be pulled, {@code false} otherwise. 45391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn */ 45491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn private boolean isCallPullPermitted(boolean isNetworkPullable, int videoState) { 45591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn if (VideoProfile.isVideo(videoState) && !mIsVideoCapable) { 45691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn // If the external call is a video call and the local device does not have video 45791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn // capability at this time, it cannot be pulled. 45891c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn return false; 45991c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 46091c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 46191c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn if (mHasActiveCalls) { 46291c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn // If there are active calls on the local device, the call cannot be pulled. 46391c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn return false; 46491c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 46591c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn 46691c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn return isNetworkPullable; 46791c714c06cc426b4f1af05a758c4d560b16f6d24Tyler Gunn } 468fec523bdc5d2b6dd90212c8076bf34bcc2ab08b2Tyler Gunn} 469