Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +115 −49 Original line number Diff line number Diff line Loading @@ -302,6 +302,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private ImsCall mCallExpectedToResume = null; private boolean mAllowEmergencyVideoCalls = false; private boolean mIgnoreDataEnabledChangedForVideoCalls = false; private boolean mIsViLteDataMetered = false; /** * Listeners to changes in the phone state. Intended for use by other interested IMS components Loading Loading @@ -977,6 +978,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL); mIgnoreDataEnabledChangedForVideoCalls = carrierConfig.getBoolean( CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS); mIsViLteDataMetered = carrierConfig.getBoolean( CarrierConfigManager.KEY_VILTE_DATA_IS_METERED_BOOL); mSupportPauseVideo = carrierConfig.getBoolean( CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL); Loading Loading @@ -2513,20 +2516,29 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER); } 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 boolean isHandoverFromWifi = srcAccessTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; if (mNotifyHandoverVideoFromWifiToLTE && isHandoverFromWifi && imsCall.isVideoCall()) { if (isHandoverFromWifi && imsCall.isVideoCall()) { if (mNotifyHandoverVideoFromWifiToLTE) { log("onCallHandover :: notifying of WIFI to LTE handover."); ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { conn.onConnectionEvent( TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE, null); } else { loge("onCallHandover :: failed to notify of handover; connection is null."); } if (!mIsDataEnabled && mIsViLteDataMetered) { // Call was downgraded from WIFI to LTE and data is metered; downgrade the // call now. downgradeVideoCall(ImsReasonInfo.CODE_DATA_DISABLED, conn); } } } else { loge("onCallHandover :: connection null."); } mMetrics.writeOnImsCallHandoverEvent(mPhone.getPhoneId(), TelephonyCallSession.Event.Type.IMS_CALL_HANDOVER, imsCall.getCallSession(), Loading Loading @@ -3349,17 +3361,18 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setDataEnabled(enabled); mIsDataEnabled = enabled; if (mIgnoreDataEnabledChangedForVideoCalls) { log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " due to carrier policy."); if (!mIsViLteDataMetered) { log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " - carrier policy " + "indicates that data is not metered for ViLTE calls."); return; } if (mIgnoreDataEnabledChangedForVideoCalls) { log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " due to carrier policy."); return; // Inform connections that data has been disabled to ensure we turn off video capability // if this is an LTE call. for (ImsPhoneConnection conn : mConnections) { conn.handleDataEnabledChange(enabled); } if (!enabled) { int reasonCode; if (reason == DataEnabledSettings.REASON_POLICY_DATA_ENABLED) { reasonCode = ImsReasonInfo.CODE_DATA_LIMIT_REACHED; Loading @@ -3370,6 +3383,24 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { reasonCode = ImsReasonInfo.CODE_DATA_DISABLED; } // Potentially send connection events so the InCall UI knows that video calls are being // downgraded due to data being enabled/disabled. maybeNotifyDataDisabled(enabled, reasonCode); // Handle video state changes required as a result of data being enabled/disabled. handleDataEnabledChange(enabled, reasonCode); // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before // the carrier config has loaded and will deregister IMS. if (!mShouldUpdateImsConfigOnDisconnect && reason != DataEnabledSettings.REASON_REGISTERED) { // This will call into updateVideoCallFeatureValue and eventually all clients will be // asynchronously notified that the availability of VT over LTE has changed. ImsManager.updateImsServiceConfig(mPhone.getContext(), mPhone.getPhoneId(), true); } } private void maybeNotifyDataDisabled(boolean enabled, int reasonCode) { if (!enabled) { // If data is disabled while there are ongoing VT calls which are not taking place over // wifi, then they should be disconnected to prevent the user from incurring further // data charges. Loading @@ -3389,27 +3420,38 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { conn.onConnectionEvent( TelephonyManager.EVENT_DOWNGRADE_DATA_LIMIT_REACHED, null); } modifyVideoCall(imsCall, VideoProfile.STATE_AUDIO_ONLY); } else if (mSupportPauseVideo) { // The carrier supports video pause signalling, so pause the video. mShouldUpdateImsConfigOnDisconnect = true; conn.pauseVideo(VideoPauseTracker.SOURCE_DATA_ENABLED); } else { // At this point the only choice we have is to terminate the call. try { imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED, reasonCode); } catch (ImsException ie) { loge("Couldn't terminate call " + imsCall); } } } } } /** * Handles changes to the enabled state of mobile data. * When data is disabled, handles auto-downgrade of video calls over LTE. * When data is enabled, handled resuming of video calls paused when data was disabled. * @param enabled {@code true} if mobile data is enabled, {@code false} if mobile data is * disabled. * @param reasonCode The {@link ImsReasonInfo} code for the data enabled state change. */ private void handleDataEnabledChange(boolean enabled, int reasonCode) { if (!enabled) { // If data is disabled while there are ongoing VT calls which are not taking place over // wifi, then they should be disconnected to prevent the user from incurring further // data charges. for (ImsPhoneConnection conn : mConnections) { ImsCall imsCall = conn.getImsCall(); if (imsCall != null && imsCall.isVideoCall() && !imsCall.isWifiCall()) { log("handleDataEnabledChange - downgrading " + conn); downgradeVideoCall(reasonCode, conn); } } } else if (mSupportPauseVideo) { // Data was re-enabled, so un-pause previously paused video calls. for (ImsPhoneConnection conn : mConnections) { // If video is paused, check to see if there are any pending pauses due to enabled // state of data changing. log("onDataEnabledChanged - resuming " + conn); log("handleDataEnabledChange - resuming " + conn); if (VideoProfile.isPaused(conn.getVideoState()) && conn.wasVideoPausedFromSource(VideoPauseTracker.SOURCE_DATA_ENABLED)) { // The data enabled state was a cause of a pending pause, so potentially Loading @@ -3419,15 +3461,39 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } mShouldUpdateImsConfigOnDisconnect = false; } } /** * Handles downgrading a video call. The behavior depends on carrier capabilities; we will * attempt to take one of the following actions (in order of precedence): * 1. If supported by the carrier, the call will be downgraded to an audio-only call. * 2. If the carrier supports video pause signalling, the video will be paused. * 3. The call will be disconnected. * @param reasonCode The {@link ImsReasonInfo} reason code for the downgrade. * @param conn The {@link ImsPhoneConnection} to downgrade. */ private void downgradeVideoCall(int reasonCode, ImsPhoneConnection conn) { ImsCall imsCall = conn.getImsCall(); if (imsCall != null) { if (conn.hasCapabilities( Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL | Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE)) { // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before // the carrier config has loaded and will deregister IMS. if (!mShouldUpdateImsConfigOnDisconnect && reason != DataEnabledSettings.REASON_REGISTERED) { // This will call into updateVideoCallFeatureValue and eventually all clients will be // asynchronously notified that the availability of VT over LTE has changed. ImsManager.updateImsServiceConfig(mPhone.getContext(), mPhone.getPhoneId(), true); // If the carrier supports downgrading to voice, then we can simply issue a // downgrade to voice instead of terminating the call. modifyVideoCall(imsCall, VideoProfile.STATE_AUDIO_ONLY); } else if (mSupportPauseVideo) { // The carrier supports video pause signalling, so pause the video. mShouldUpdateImsConfigOnDisconnect = true; conn.pauseVideo(VideoPauseTracker.SOURCE_DATA_ENABLED); } else { // At this point the only choice we have is to terminate the call. try { imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED, reasonCode); } catch (ImsException ie) { loge("Couldn't terminate call " + imsCall); } } } } Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java +25 −2 Original line number Diff line number Diff line Loading @@ -111,6 +111,14 @@ public class ImsPhoneConnection extends Connection implements */ private boolean mIsMergeInProcess = false; /** * Used as an override to determine whether video is locally available for this call. * This allows video availability to be overridden in the case that the modem says video is * currently available, but mobile data is off and the carrier is metering data for video * calls. */ private boolean mIsVideoEnabled = true; //***** Event Constants private static final int EVENT_DTMF_DONE = 1; private static final int EVENT_PAUSE_DONE = 2; Loading Loading @@ -246,11 +254,15 @@ public class ImsPhoneConnection extends Connection implements return (a == null) ? (b == null) : (b != null && a.startsWith (b)); } private static int applyLocalCallCapabilities(ImsCallProfile localProfile, int capabilities) { Rlog.w(LOG_TAG, "applyLocalCallCapabilities - localProfile = "+localProfile); private int applyLocalCallCapabilities(ImsCallProfile localProfile, int capabilities) { Rlog.i(LOG_TAG, "applyLocalCallCapabilities - localProfile = " + localProfile); capabilities = removeCapability(capabilities, Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL); if (!mIsVideoEnabled) { Rlog.i(LOG_TAG, "applyLocalCallCapabilities - disabling video (overidden)"); return capabilities; } switch (localProfile.mCallType) { case ImsCallProfile.CALL_TYPE_VT: // Fall-through Loading Loading @@ -1229,4 +1241,15 @@ public class ImsPhoneConnection extends Connection implements updateVideoState(newVideoState); mShouldIgnoreVideoStateChanges = false; } public void handleDataEnabledChange(boolean isDataEnabled) { mIsVideoEnabled = isDataEnabled; Rlog.i(LOG_TAG, "handleDataEnabledChange: isDataEnabled=" + isDataEnabled + "; updating local video availability."); updateMediaCapabilities(getImsCall()); if (mImsVideoCallProviderWrapper != null) { mImsVideoCallProviderWrapper.setIsVideoEnabled( hasCapabilities(Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL)); } } } Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +115 −49 Original line number Diff line number Diff line Loading @@ -302,6 +302,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private ImsCall mCallExpectedToResume = null; private boolean mAllowEmergencyVideoCalls = false; private boolean mIgnoreDataEnabledChangedForVideoCalls = false; private boolean mIsViLteDataMetered = false; /** * Listeners to changes in the phone state. Intended for use by other interested IMS components Loading Loading @@ -977,6 +978,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL); mIgnoreDataEnabledChangedForVideoCalls = carrierConfig.getBoolean( CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS); mIsViLteDataMetered = carrierConfig.getBoolean( CarrierConfigManager.KEY_VILTE_DATA_IS_METERED_BOOL); mSupportPauseVideo = carrierConfig.getBoolean( CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL); Loading Loading @@ -2513,20 +2516,29 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER); } 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 boolean isHandoverFromWifi = srcAccessTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN && targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; if (mNotifyHandoverVideoFromWifiToLTE && isHandoverFromWifi && imsCall.isVideoCall()) { if (isHandoverFromWifi && imsCall.isVideoCall()) { if (mNotifyHandoverVideoFromWifiToLTE) { log("onCallHandover :: notifying of WIFI to LTE handover."); ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { conn.onConnectionEvent( TelephonyManager.EVENT_HANDOVER_VIDEO_FROM_WIFI_TO_LTE, null); } else { loge("onCallHandover :: failed to notify of handover; connection is null."); } if (!mIsDataEnabled && mIsViLteDataMetered) { // Call was downgraded from WIFI to LTE and data is metered; downgrade the // call now. downgradeVideoCall(ImsReasonInfo.CODE_DATA_DISABLED, conn); } } } else { loge("onCallHandover :: connection null."); } mMetrics.writeOnImsCallHandoverEvent(mPhone.getPhoneId(), TelephonyCallSession.Event.Type.IMS_CALL_HANDOVER, imsCall.getCallSession(), Loading Loading @@ -3349,17 +3361,18 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setDataEnabled(enabled); mIsDataEnabled = enabled; if (mIgnoreDataEnabledChangedForVideoCalls) { log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " due to carrier policy."); if (!mIsViLteDataMetered) { log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " - carrier policy " + "indicates that data is not metered for ViLTE calls."); return; } if (mIgnoreDataEnabledChangedForVideoCalls) { log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " due to carrier policy."); return; // Inform connections that data has been disabled to ensure we turn off video capability // if this is an LTE call. for (ImsPhoneConnection conn : mConnections) { conn.handleDataEnabledChange(enabled); } if (!enabled) { int reasonCode; if (reason == DataEnabledSettings.REASON_POLICY_DATA_ENABLED) { reasonCode = ImsReasonInfo.CODE_DATA_LIMIT_REACHED; Loading @@ -3370,6 +3383,24 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { reasonCode = ImsReasonInfo.CODE_DATA_DISABLED; } // Potentially send connection events so the InCall UI knows that video calls are being // downgraded due to data being enabled/disabled. maybeNotifyDataDisabled(enabled, reasonCode); // Handle video state changes required as a result of data being enabled/disabled. handleDataEnabledChange(enabled, reasonCode); // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before // the carrier config has loaded and will deregister IMS. if (!mShouldUpdateImsConfigOnDisconnect && reason != DataEnabledSettings.REASON_REGISTERED) { // This will call into updateVideoCallFeatureValue and eventually all clients will be // asynchronously notified that the availability of VT over LTE has changed. ImsManager.updateImsServiceConfig(mPhone.getContext(), mPhone.getPhoneId(), true); } } private void maybeNotifyDataDisabled(boolean enabled, int reasonCode) { if (!enabled) { // If data is disabled while there are ongoing VT calls which are not taking place over // wifi, then they should be disconnected to prevent the user from incurring further // data charges. Loading @@ -3389,27 +3420,38 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { conn.onConnectionEvent( TelephonyManager.EVENT_DOWNGRADE_DATA_LIMIT_REACHED, null); } modifyVideoCall(imsCall, VideoProfile.STATE_AUDIO_ONLY); } else if (mSupportPauseVideo) { // The carrier supports video pause signalling, so pause the video. mShouldUpdateImsConfigOnDisconnect = true; conn.pauseVideo(VideoPauseTracker.SOURCE_DATA_ENABLED); } else { // At this point the only choice we have is to terminate the call. try { imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED, reasonCode); } catch (ImsException ie) { loge("Couldn't terminate call " + imsCall); } } } } } /** * Handles changes to the enabled state of mobile data. * When data is disabled, handles auto-downgrade of video calls over LTE. * When data is enabled, handled resuming of video calls paused when data was disabled. * @param enabled {@code true} if mobile data is enabled, {@code false} if mobile data is * disabled. * @param reasonCode The {@link ImsReasonInfo} code for the data enabled state change. */ private void handleDataEnabledChange(boolean enabled, int reasonCode) { if (!enabled) { // If data is disabled while there are ongoing VT calls which are not taking place over // wifi, then they should be disconnected to prevent the user from incurring further // data charges. for (ImsPhoneConnection conn : mConnections) { ImsCall imsCall = conn.getImsCall(); if (imsCall != null && imsCall.isVideoCall() && !imsCall.isWifiCall()) { log("handleDataEnabledChange - downgrading " + conn); downgradeVideoCall(reasonCode, conn); } } } else if (mSupportPauseVideo) { // Data was re-enabled, so un-pause previously paused video calls. for (ImsPhoneConnection conn : mConnections) { // If video is paused, check to see if there are any pending pauses due to enabled // state of data changing. log("onDataEnabledChanged - resuming " + conn); log("handleDataEnabledChange - resuming " + conn); if (VideoProfile.isPaused(conn.getVideoState()) && conn.wasVideoPausedFromSource(VideoPauseTracker.SOURCE_DATA_ENABLED)) { // The data enabled state was a cause of a pending pause, so potentially Loading @@ -3419,15 +3461,39 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } mShouldUpdateImsConfigOnDisconnect = false; } } /** * Handles downgrading a video call. The behavior depends on carrier capabilities; we will * attempt to take one of the following actions (in order of precedence): * 1. If supported by the carrier, the call will be downgraded to an audio-only call. * 2. If the carrier supports video pause signalling, the video will be paused. * 3. The call will be disconnected. * @param reasonCode The {@link ImsReasonInfo} reason code for the downgrade. * @param conn The {@link ImsPhoneConnection} to downgrade. */ private void downgradeVideoCall(int reasonCode, ImsPhoneConnection conn) { ImsCall imsCall = conn.getImsCall(); if (imsCall != null) { if (conn.hasCapabilities( Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL | Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE)) { // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before // the carrier config has loaded and will deregister IMS. if (!mShouldUpdateImsConfigOnDisconnect && reason != DataEnabledSettings.REASON_REGISTERED) { // This will call into updateVideoCallFeatureValue and eventually all clients will be // asynchronously notified that the availability of VT over LTE has changed. ImsManager.updateImsServiceConfig(mPhone.getContext(), mPhone.getPhoneId(), true); // If the carrier supports downgrading to voice, then we can simply issue a // downgrade to voice instead of terminating the call. modifyVideoCall(imsCall, VideoProfile.STATE_AUDIO_ONLY); } else if (mSupportPauseVideo) { // The carrier supports video pause signalling, so pause the video. mShouldUpdateImsConfigOnDisconnect = true; conn.pauseVideo(VideoPauseTracker.SOURCE_DATA_ENABLED); } else { // At this point the only choice we have is to terminate the call. try { imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED, reasonCode); } catch (ImsException ie) { loge("Couldn't terminate call " + imsCall); } } } } Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java +25 −2 Original line number Diff line number Diff line Loading @@ -111,6 +111,14 @@ public class ImsPhoneConnection extends Connection implements */ private boolean mIsMergeInProcess = false; /** * Used as an override to determine whether video is locally available for this call. * This allows video availability to be overridden in the case that the modem says video is * currently available, but mobile data is off and the carrier is metering data for video * calls. */ private boolean mIsVideoEnabled = true; //***** Event Constants private static final int EVENT_DTMF_DONE = 1; private static final int EVENT_PAUSE_DONE = 2; Loading Loading @@ -246,11 +254,15 @@ public class ImsPhoneConnection extends Connection implements return (a == null) ? (b == null) : (b != null && a.startsWith (b)); } private static int applyLocalCallCapabilities(ImsCallProfile localProfile, int capabilities) { Rlog.w(LOG_TAG, "applyLocalCallCapabilities - localProfile = "+localProfile); private int applyLocalCallCapabilities(ImsCallProfile localProfile, int capabilities) { Rlog.i(LOG_TAG, "applyLocalCallCapabilities - localProfile = " + localProfile); capabilities = removeCapability(capabilities, Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL); if (!mIsVideoEnabled) { Rlog.i(LOG_TAG, "applyLocalCallCapabilities - disabling video (overidden)"); return capabilities; } switch (localProfile.mCallType) { case ImsCallProfile.CALL_TYPE_VT: // Fall-through Loading Loading @@ -1229,4 +1241,15 @@ public class ImsPhoneConnection extends Connection implements updateVideoState(newVideoState); mShouldIgnoreVideoStateChanges = false; } public void handleDataEnabledChange(boolean isDataEnabled) { mIsVideoEnabled = isDataEnabled; Rlog.i(LOG_TAG, "handleDataEnabledChange: isDataEnabled=" + isDataEnabled + "; updating local video availability."); updateMediaCapabilities(getImsCall()); if (mImsVideoCallProviderWrapper != null) { mImsVideoCallProviderWrapper.setIsVideoEnabled( hasCapabilities(Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL)); } } }