From d1623f4fdaa16217dc8e5d9321301a0157740d5d Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Tue, 31 Oct 2017 09:33:36 -0700 Subject: Increase waiting state timeout from 30s to 5min. Test: runtest --path frameworks/opt/telephony/tests/telephonytests/src/com/android/ internal/telephony/gsm/GsmInboundSmsHandlerTest.java Bug: 68704659 Bug: 69475609 Change-Id: I79bded1ca345978075836bf247fccb53bc55caa5 (cherry picked from commit 8907a6dcd82e140f8fe47c02fda8ffd15964aba6) --- src/java/com/android/internal/telephony/InboundSmsHandler.java | 4 ++-- .../com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java index 391de50019..2d663cd713 100644 --- a/src/java/com/android/internal/telephony/InboundSmsHandler.java +++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java @@ -165,9 +165,9 @@ public abstract class InboundSmsHandler extends StateMachine { * state */ private static final int EVENT_STATE_TIMEOUT = 10; - /** Timeout duration for EVENT_STATE_TIMEOUT */ + /** Timeout duration for EVENT_STATE_TIMEOUT (5 minutes) */ @VisibleForTesting - public static final int STATE_TIMEOUT = 30000; + public static final int STATE_TIMEOUT = 5 * 60 * 1000; /** Wakelock release delay when returning to idle state. */ private static final int WAKELOCK_TIMEOUT = 3000; diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java index 02758ac397..6e14acada1 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java @@ -47,6 +47,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Telephony; import android.support.test.filters.FlakyTest; +import android.support.test.filters.LargeTest; import android.support.test.filters.MediumTest; import android.test.mock.MockContentResolver; @@ -785,7 +786,7 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { @FlakyTest @Ignore @Test - @MediumTest + @LargeTest public void testWaitingStateTimeout() throws Exception { transitionFromStartupToIdle(); -- cgit v1.2.3 From e7db19e88f3b1ff3f1d555dc8f7eeb0eb8c78155 Mon Sep 17 00:00:00 2001 From: Tyler Gunn Date: Fri, 1 Dec 2017 16:13:17 +0000 Subject: Do not notify of WIFI to LTE handover for disconnected call. It is possible for the onCallHandover callback to indicate that a call in the process of disconnecting or which has been disconnected already has handed over from WIFI to LTE. We suppress the connection event if this is the case. Test: Reproduced bug, and then confirmed fix corrects the issue. Bug: 65490850 Merged-In: Ibaff84dc7e4c3b628d4f9f5b2fdd819220a9d185 Change-Id: I460db6c122188d9bd9a4db4e93cee44bf9c63905 (cherry picked from commit 3e227d75e46ad8fa928ebfccbc3a90db65429968) --- .../internal/telephony/imsphone/ImsPhoneCallTracker.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java index 072da68ed9..a5020ab97f 100644 --- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java @@ -2552,9 +2552,17 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; if (isHandoverFromWifi && imsCall.isVideoCall()) { if (mNotifyHandoverVideoFromWifiToLTE && mIsDataEnabled) { - log("onCallHandover :: notifying of WIFI to LTE handover."); - conn.onConnectionEvent( - TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE, null); + if (conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) { + log("onCallHandover :: notifying of WIFI to LTE handover."); + conn.onConnectionEvent( + TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE, null); + } else { + // Call has already had a disconnect request issued by the user or is + // in the process of disconnecting; do not inform the UI of this as it + // is not relevant. + log("onCallHandover :: skip notify of WIFI to LTE handover for " + + "disconnected call."); + } } if (!mIsDataEnabled && mIsViLteDataMetered) { -- cgit v1.2.3 From 8d9cccc1c22f8404bf7780c1d965a8ba7afae1e2 Mon Sep 17 00:00:00 2001 From: Tyler Gunn Date: Thu, 14 Dec 2017 14:20:19 -0800 Subject: Add support for notification of midcall video call radio handovers. Adding support for video calls to: - Notification of successful LTE to WIFI handover - Notification of failure to handover from LTE to WIFI. If there is a handover from WIFI to LTE (or the initial handover from lte to WIFI fails at the start of a call), we enable a connectivity listener to track when a new WIFI network becomes available. If a new wifi network becomes available and there is no handover to WIFI before a 1 min time expires, we warn the user (existing connection event) that we couldn't handover to wifi. If the handover to WIFI is successful, we send a connection event which dialer will use to show a toast for the handover. Test: Manual, added unit tests. Bug: 65490850 Change-Id: I7fa16003e7309d40df0654c2992c823ed4d12e28 (cherry picked from commit 02761d2406c0197cebd255b575f161f5145efbb3) --- .../telephony/imsphone/ImsPhoneCallTracker.java | 190 +++++++++++++++++++-- .../imsphone/ImsPhoneCallTrackerTest.java | 65 ++++++- 2 files changed, 239 insertions(+), 16 deletions(-) diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java index a5020ab97f..bdb1e11863 100644 --- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java @@ -24,7 +24,10 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.net.NetworkRequest; import android.net.NetworkStats; import android.net.Uri; import android.os.AsyncResult; @@ -227,6 +230,24 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } }; + /** + * Tracks whether we are currently monitoring network connectivity for the purpose of warning + * the user of an inability to handover from LTE to WIFI for video calls. + */ + private boolean mIsMonitoringConnectivity = false; + + /** + * Network callback used to schedule the handover check when a wireless network connects. + */ + private ConnectivityManager.NetworkCallback mNetworkCallback = + new ConnectivityManager.NetworkCallback() { + @Override + public void onAvailable(Network network) { + Rlog.i(LOG_TAG, "Network available: " + network); + scheduleHandoverCheck(); + } + }; + //***** Constants static final int MAX_CONNECTIONS = 7; @@ -579,6 +600,22 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { */ private boolean mNotifyHandoverVideoFromWifiToLTE = false; + /** + * Carrier configuration option which determines whether the carrier wants to inform the user + * when a video call is handed over from LTE to WIFI. + * See {@link CarrierConfigManager#KEY_NOTIFY_HANDOVER_VIDEO_FROM_LTE_TO_WIFI_BOOL} for more + * information. + */ + private boolean mNotifyHandoverVideoFromLTEToWifi = false; + + /** + * When {@code} false, indicates that no handover from LTE to WIFI has occurred during the start + * of the call. + * When {@code true}, indicates that the start of call handover from LTE to WIFI has been + * attempted (it may have suceeded or failed). + */ + private boolean mHasPerformedStartOfCallHandover = false; + /** * Carrier configuration option which determines whether the carrier supports the * {@link VideoProfile#STATE_PAUSED} signalling. @@ -986,6 +1023,16 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return; } + updateCarrierConfigCache(carrierConfig); + } + + /** + * Updates the local carrier config cache from a bundle obtained from the carrier config + * manager. Also supports unit testing by injecting configuration at test time. + * @param carrierConfig The config bundle. + */ + @VisibleForTesting + public void updateCarrierConfigCache(PersistableBundle carrierConfig) { mAllowEmergencyVideoCalls = carrierConfig.getBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL); mTreatDowngradedVideoCallsAsVideoCalls = @@ -1003,6 +1050,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL); mNotifyHandoverVideoFromWifiToLTE = carrierConfig.getBoolean( CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL); + mNotifyHandoverVideoFromLTEToWifi = carrierConfig.getBoolean( + CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_LTE_TO_WIFI_BOOL); mIgnoreDataEnabledChangedForVideoCalls = carrierConfig.getBoolean( CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS); mIsViLteDataMetered = carrierConfig.getBoolean( @@ -2016,13 +2065,18 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE, DisconnectCause.NOT_DISCONNECTED); - if (mNotifyVtHandoverToWifiFail && - !imsCall.isWifiCall() && imsCall.isVideoCall() && isWifiConnected()) { - // Schedule check to see if handover succeeded. - sendMessageDelayed(obtainMessage(EVENT_CHECK_FOR_WIFI_HANDOVER, imsCall), - HANDOVER_TO_WIFI_TIMEOUT_MS); + if (mNotifyVtHandoverToWifiFail && imsCall.isVideoCall() && !imsCall.isWifiCall()) { + if (isWifiConnected()) { + // Schedule check to see if handover succeeded. + sendMessageDelayed(obtainMessage(EVENT_CHECK_FOR_WIFI_HANDOVER, imsCall), + HANDOVER_TO_WIFI_TIMEOUT_MS); + } else { + // No wifi connectivity, so keep track of network availability for potential + // handover. + registerForConnectivityChanges(); + } } - + mHasPerformedStartOfCallHandover = false; mMetrics.writeOnImsCallStarted(mPhone.getPhoneId(), imsCall.getCallSession()); } @@ -2538,18 +2592,35 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { boolean isHandoverToWifi = srcAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN && srcAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN && targetAccessTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; - if (isHandoverToWifi) { - // If we handed over to wifi successfully, don't check for failure in the future. - removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER); - } + // Only consider it a handover from WIFI if the source and target radio tech is known. + boolean isHandoverFromWifi = + srcAccessTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN + && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { - // Only consider it a handover from WIFI if the source and target radio tech is known. - boolean isHandoverFromWifi = - srcAccessTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN - && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN - && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; + if (conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) { + if (isHandoverToWifi) { + removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER); + + if (mNotifyHandoverVideoFromLTEToWifi && mHasPerformedStartOfCallHandover) { + // This is a handover which happened mid-call (ie not the start of call + // handover from LTE to WIFI), so we'll notify the InCall UI. + conn.onConnectionEvent( + TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_LTE_TO_WIFI, null); + } + + // We are on WIFI now so no need to get notified of network availability. + unregisterForConnectivityChanges(); + } else if (isHandoverFromWifi && imsCall.isVideoCall()) { + // A video call just dropped from WIFI to LTE; we want to be informed if a + // new WIFI + // network comes into range. + registerForConnectivityChanges(); + } + } + if (isHandoverFromWifi && imsCall.isVideoCall()) { if (mNotifyHandoverVideoFromWifiToLTE && mIsDataEnabled) { if (conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) { @@ -2575,6 +2646,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { loge("onCallHandover :: connection null."); } + if (!mHasPerformedStartOfCallHandover) { + mHasPerformedStartOfCallHandover = true; + } mMetrics.writeOnImsCallHandoverEvent(mPhone.getPhoneId(), TelephonyCallSession.Event.Type.IMS_CALL_HANDOVER, imsCall.getCallSession(), srcAccessTech, targetAccessTech, reasonInfo); @@ -2600,11 +2674,20 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { // If we know we failed to handover, don't check for failure in the future. removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER); + if (imsCall.isVideoCall() + && conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) { + // Start listening for a WIFI network to come into range for potential handover. + registerForConnectivityChanges(); + } + if (mNotifyVtHandoverToWifiFail) { // Only notify others if carrier config indicates to do so. conn.onHandoverToWifiFailed(); } } + if (!mHasPerformedStartOfCallHandover) { + mHasPerformedStartOfCallHandover = true; + } } @Override @@ -2682,6 +2765,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) { if (DBG) log("mImsUssdListener onCallTerminated reasonCode=" + reasonInfo.getCode()); removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER); + mHasPerformedStartOfCallHandover = false; + unregisterForConnectivityChanges(); if (imsCall == mUssdSession) { mUssdSession = null; @@ -2950,12 +3035,24 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { case EVENT_CHECK_FOR_WIFI_HANDOVER: if (msg.obj instanceof ImsCall) { ImsCall imsCall = (ImsCall) msg.obj; + if (imsCall != mForegroundCall.getImsCall()) { + Rlog.i(LOG_TAG, "handoverCheck: no longer FG; check skipped."); + unregisterForConnectivityChanges(); + // Handover check and its not the foreground call any more. + return; + } if (!imsCall.isWifiCall()) { // Call did not handover to wifi, notify of handover failure. ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { + Rlog.i(LOG_TAG, "handoverCheck: handover failed."); conn.onHandoverToWifiFailed(); } + + if (imsCall.isVideoCall() + && conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) { + registerForConnectivityChanges(); + } } } break; @@ -3566,6 +3663,64 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return false; } + /** + * Registers for changes to network connectivity. Specifically requests the availability of new + * WIFI networks which an IMS video call could potentially hand over to. + */ + private void registerForConnectivityChanges() { + if (mIsMonitoringConnectivity || !mNotifyVtHandoverToWifiFail) { + return; + } + ConnectivityManager cm = (ConnectivityManager) mPhone.getContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm != null) { + Rlog.i(LOG_TAG, "registerForConnectivityChanges"); + NetworkCapabilities capabilities = new NetworkCapabilities(); + capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); + NetworkRequest.Builder builder = new NetworkRequest.Builder(); + builder.setCapabilities(capabilities); + cm.registerNetworkCallback(builder.build(), mNetworkCallback); + mIsMonitoringConnectivity = true; + } + } + + /** + * Unregister for connectivity changes. Will be called when a call disconnects or if the call + * ends up handing over to WIFI. + */ + private void unregisterForConnectivityChanges() { + if (!mIsMonitoringConnectivity || !mNotifyVtHandoverToWifiFail) { + return; + } + ConnectivityManager cm = (ConnectivityManager) mPhone.getContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm != null) { + Rlog.i(LOG_TAG, "unregisterForConnectivityChanges"); + cm.unregisterNetworkCallback(mNetworkCallback); + mIsMonitoringConnectivity = false; + } + } + + /** + * If the foreground call is a video call, schedule a handover check if one is not already + * scheduled. This method is intended ONLY for use when scheduling to watch for mid-call + * handovers. + */ + private void scheduleHandoverCheck() { + ImsCall fgCall = mForegroundCall.getImsCall(); + ImsPhoneConnection conn = mForegroundCall.getFirstConnection(); + if (!mNotifyVtHandoverToWifiFail || fgCall == null || !fgCall.isVideoCall() || conn == null + || conn.getDisconnectCause() != DisconnectCause.NOT_DISCONNECTED) { + return; + } + + if (!hasMessages(EVENT_CHECK_FOR_WIFI_HANDOVER)) { + Rlog.i(LOG_TAG, "scheduleHandoverCheck: schedule"); + sendMessageDelayed(obtainMessage(EVENT_CHECK_FOR_WIFI_HANDOVER, fgCall), + HANDOVER_TO_WIFI_TIMEOUT_MS); + } + } + /** * @return {@code true} if downgrading of a video call to audio is supported. */ @@ -3573,6 +3728,11 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return mSupportDowngradeVtToAudio; } + @VisibleForTesting + public void setDataEnabled(boolean isDataEnabled) { + mIsDataEnabled = isDataEnabled; + } + private void handleFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures, int[] disabledFeatures) { if (serviceClass == ImsServiceClass.MMTEL) { diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java index 989cd64c32..71f4cc4f2e 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.isNull; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -42,10 +43,14 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; +import android.os.PersistableBundle; import android.support.test.filters.FlakyTest; import android.telecom.VideoProfile; +import android.telephony.CarrierConfigManager; import android.telephony.DisconnectCause; import android.telephony.PhoneNumberUtils; +import android.telephony.ServiceState; +import android.telephony.TelephonyManager; import android.telephony.ims.feature.ImsFeature; import android.test.suitebuilder.annotation.SmallTest; @@ -88,6 +93,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsCallSession mImsCallSession; @Mock private SharedPreferences mSharedPreferences; + @Mock + private ImsPhoneConnection.Listener mImsPhoneConnectionListener; private Handler mCTHander; private class ImsCTHandlerThread extends HandlerThread { @@ -103,6 +110,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { ImsReasonInfo.CODE_ANSWERED_ELSEWHERE); mCTUT.addReasonCodeRemapping(510, "Call answered elsewhere.", ImsReasonInfo.CODE_ANSWERED_ELSEWHERE); + mCTUT.setDataEnabled(true); mCTHander = new Handler(mCTUT.getLooper()); setReady(true); } @@ -156,7 +164,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { } }).when(mImsCall).hold(); - doReturn(mImsCallSession).when(mImsCall).getCallSession(); + mImsCall.attachSession(mImsCallSession); } @Before @@ -167,6 +175,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { mImsManagerInstances.put(mImsPhone.getPhoneId(), mImsManager); mImsCall = spy(new ImsCall(mContext, mImsCallProfile)); mSecondImsCall = spy(new ImsCall(mContext, mImsCallProfile)); + mImsPhoneConnectionListener = mock(ImsPhoneConnection.Listener.class); imsCallMocking(mImsCall); imsCallMocking(mSecondImsCall); doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceStatus(); @@ -189,6 +198,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { public ImsCall answer(InvocationOnMock invocation) throws Throwable { mImsCallListener = (ImsCall.Listener) invocation.getArguments()[2]; + mImsCall.setListener(mImsCallListener); return mImsCall; } }).when(mImsManager).takeCall(eq(mServiceId), (Intent) any(), (ImsCall.Listener) any()); @@ -198,6 +208,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { public ImsCall answer(InvocationOnMock invocation) throws Throwable { mImsCallListener = (ImsCall.Listener) invocation.getArguments()[3]; + mSecondImsCall.setListener(mImsCallListener); return mSecondImsCall; } }).when(mImsManager).makeCall(eq(mServiceId), eq(mImsCallProfile), (String []) any(), @@ -262,6 +273,9 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); assertTrue(mCTUT.mRingingCall.isRinging()); assertEquals(1, mCTUT.mRingingCall.getConnections().size()); + ImsPhoneConnection connection = + (ImsPhoneConnection) mCTUT.mRingingCall.getConnections().get(0); + connection.addListener(mImsPhoneConnectionListener); } @Test @@ -570,6 +584,55 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { nullable(ImsConnectionStateListener.class)); } + /** + * Test notification of handover from LTE to WIFI and WIFI to LTE and ensure that the expected + * connection events are sent. + */ + @Test + @SmallTest + public void testNotifyHandovers() { + setupCarrierConfig(); + + //establish a MT call + testImsMTCallAccept(); + ImsPhoneConnection connection = + (ImsPhoneConnection) mCTUT.mForegroundCall.getConnections().get(0); + ImsCall call = connection.getImsCall(); + // Needs to be a video call to see this signalling. + doReturn(true).when(mImsCallProfile).isVideoCall(); + + // First handover from LTE to WIFI; this takes us into a mid-call state. + call.getImsCallSessionListenerProxy().callSessionHandover(call.getCallSession(), + ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, + new ImsReasonInfo()); + // Handover back to LTE. + call.getImsCallSessionListenerProxy().callSessionHandover(call.getCallSession(), + ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, ServiceState.RIL_RADIO_TECHNOLOGY_LTE, + new ImsReasonInfo()); + verify(mImsPhoneConnectionListener).onConnectionEvent(eq( + TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE), isNull()); + + // Finally hand back to WIFI + call.getImsCallSessionListenerProxy().callSessionHandover(call.getCallSession(), + ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, + new ImsReasonInfo()); + verify(mImsPhoneConnectionListener).onConnectionEvent(eq( + TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_LTE_TO_WIFI), isNull()); + } + + /** + * Configure carrier config options relevant to the unit test. + */ + public void setupCarrierConfig() { + PersistableBundle bundle = new PersistableBundle(); + bundle.putBoolean(CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_LTE_TO_WIFI_BOOL, + true); + bundle.putBoolean(CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL, + true); + bundle.putBoolean(CarrierConfigManager.KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, true); + mCTUT.updateCarrierConfigCache(bundle); + } + @Test @SmallTest public void testLowBatteryDisconnectMidCall() { -- cgit v1.2.3