Loading src/java/com/android/internal/telephony/dataconnection/DataConnection.java +32 −29 Original line number Diff line number Diff line Loading @@ -314,6 +314,10 @@ public class DataConnection extends StateMachine { private boolean mUnmeteredOverride; private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; private int mDataRegState = Integer.MAX_VALUE; // Indicating data connection is suspended due to temporary reasons, for example, out of // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when // data is in active state. When data is in inactive, connecting, or disconnecting, this flag // is unmeaningful. private boolean mIsSuspended; private int mDownlinkBandwidth = 14; private int mUplinkBandwidth = 14; Loading Loading @@ -487,28 +491,6 @@ public class DataConnection extends StateMachine { return new LinkProperties(mLinkProperties); } boolean isSuspended() { // Data can only be (temporarily) suspended while data is in active state if (getCurrentState() != mActiveState) return false; // never set suspend for emergency apn if (mApnSetting != null && mApnSetting.isEmergencyApn()) { return false; } // if we are not in-service change to SUSPENDED if (mDataRegState != ServiceState.STATE_IN_SERVICE) { return true; } // check for voice call and concurrency issues if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { return mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; } return false; } boolean isDisconnecting() { return getCurrentState() == mDisconnectingState || getCurrentState() == mDisconnectingErrorCreatingConnection; Loading Loading @@ -2339,8 +2321,8 @@ public class DataConnection extends StateMachine { mRilRat = drsRatPair.second; if (DBG) { log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" + " drs=" + mDataRegState + " mRilRat=" + mRilRat); + " regState=" + ServiceState.rilServiceStateToString(mDataRegState) + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat)); } mDataCallSessionStats.onDrsOrRatChanged(mRilRat); break; Loading Loading @@ -2423,12 +2405,28 @@ public class DataConnection extends StateMachine { Rlog.d(getName(), "Setting suspend state without a NetworkAgent"); } boolean suspended = isSuspended(); if (mIsSuspended != suspended) { mIsSuspended = suspended; boolean newSuspendedState = false; // Data can only be (temporarily) suspended while data is in active state if (getCurrentState() == mActiveState) { // Never set suspended for emergency apn. Emergency data connection // can work while device is not in service. if (mApnSetting != null && mApnSetting.isEmergencyApn()) { newSuspendedState = false; // If we are not in service, change to suspended. } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) { newSuspendedState = true; // Check voice/data concurrency. } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; } } // Only notify when there is a change. if (mIsSuspended != newSuspendedState) { mIsSuspended = newSuspendedState; // If data connection is active, we need to notify the new data connection state // changed event. // changed event reflecting the latest suspended state. if (isActive()) { notifyDataConnectionState(); } Loading Loading @@ -2921,6 +2919,11 @@ public class DataConnection extends StateMachine { mDisabledApnTypeBitMask |= getDisallowedApnTypes(); updateLinkPropertiesHttpProxy(); // The suspended state is only meaningful when data is in active state. We need to // make sure the suspended state is correct as soon as we enter active state. // After this, the network agent will be created with the correct suspended state // (i.e. NOT_SUSPENDED capability). updateSuspendState(); mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore, configBuilder.build(), provider, mTransportType); Loading Loading @@ -3941,7 +3944,7 @@ public class DataConnection extends StateMachine { return TelephonyManager.DATA_CONNECTING; } else if (isActive()) { // The data connection can only be suspended when it's in active state. if (isSuspended()) { if (mIsSuspended) { return TelephonyManager.DATA_SUSPENDED; } return TelephonyManager.DATA_CONNECTED; Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java +24 −6 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ import android.telephony.AccessNetworkConstants; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.telephony.ServiceState.RegState; import android.telephony.ServiceState.RilRadioTechnology; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.DataProfile; Loading @@ -63,6 +65,7 @@ import android.telephony.data.DataServiceCallback; import android.telephony.data.TrafficDescriptor; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; import com.android.internal.R; import com.android.internal.telephony.PhoneConstants; Loading Loading @@ -429,9 +432,9 @@ public class DataConnectionTest extends TelephonyTest { } private boolean isSuspended() throws Exception { Method method = DataConnection.class.getDeclaredMethod("isSuspended"); method.setAccessible(true); return (boolean) method.invoke(mDc); Field field = DataConnection.class.getDeclaredField("mIsSuspended"); field.setAccessible(true); return field.getBoolean(mDc); } private SetupResult setLinkProperties(DataCallResponse response, LinkProperties linkProperties) Loading Loading @@ -926,6 +929,12 @@ public class DataConnectionTest extends TelephonyTest { assertTrue(mDc.isInactive()); } private void serviceStateChangedEvent(@RegState int dataRegState, @RilRadioTechnology int rat) { mDc.obtainMessage(DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, new AsyncResult(null, new Pair<>(dataRegState, rat), null)).sendToTarget(); waitForMs(100); } @Test @SmallTest public void testIsIpAddress() { Loading Loading @@ -1281,24 +1290,33 @@ public class DataConnectionTest extends TelephonyTest { assertTrue(mDc.isInactive()); doReturn(mApn1).when(mApnContext).getApnSetting(); doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask(); doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed(); connectEvent(true); // Before getting any service state event, the connection should not be suspended. assertFalse(isSuspended()); // Return true if combined reg state is not in service doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getDataRegistrationState(); serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE, ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN); assertTrue(isSuspended()); // Return false if in service and concurrent voice and data is allowed doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getDataRegistrationState(); doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed(); serviceStateChangedEvent(ServiceState.STATE_IN_SERVICE, ServiceState.RIL_RADIO_TECHNOLOGY_LTE); assertFalse(isSuspended()); // Return false if in service and concurrent voice/data not allowed but call state is idle doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed(); doReturn(PhoneConstants.State.IDLE).when(mCT).getState(); mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED); waitForMs(100); assertFalse(isSuspended()); // Return true if in service, concurrent voice/data not allowed, and call state not idle doReturn(PhoneConstants.State.RINGING).when(mCT).getState(); mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED); waitForMs(100); assertTrue(isSuspended()); } Loading Loading
src/java/com/android/internal/telephony/dataconnection/DataConnection.java +32 −29 Original line number Diff line number Diff line Loading @@ -314,6 +314,10 @@ public class DataConnection extends StateMachine { private boolean mUnmeteredOverride; private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; private int mDataRegState = Integer.MAX_VALUE; // Indicating data connection is suspended due to temporary reasons, for example, out of // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when // data is in active state. When data is in inactive, connecting, or disconnecting, this flag // is unmeaningful. private boolean mIsSuspended; private int mDownlinkBandwidth = 14; private int mUplinkBandwidth = 14; Loading Loading @@ -487,28 +491,6 @@ public class DataConnection extends StateMachine { return new LinkProperties(mLinkProperties); } boolean isSuspended() { // Data can only be (temporarily) suspended while data is in active state if (getCurrentState() != mActiveState) return false; // never set suspend for emergency apn if (mApnSetting != null && mApnSetting.isEmergencyApn()) { return false; } // if we are not in-service change to SUSPENDED if (mDataRegState != ServiceState.STATE_IN_SERVICE) { return true; } // check for voice call and concurrency issues if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { return mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; } return false; } boolean isDisconnecting() { return getCurrentState() == mDisconnectingState || getCurrentState() == mDisconnectingErrorCreatingConnection; Loading Loading @@ -2339,8 +2321,8 @@ public class DataConnection extends StateMachine { mRilRat = drsRatPair.second; if (DBG) { log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" + " drs=" + mDataRegState + " mRilRat=" + mRilRat); + " regState=" + ServiceState.rilServiceStateToString(mDataRegState) + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat)); } mDataCallSessionStats.onDrsOrRatChanged(mRilRat); break; Loading Loading @@ -2423,12 +2405,28 @@ public class DataConnection extends StateMachine { Rlog.d(getName(), "Setting suspend state without a NetworkAgent"); } boolean suspended = isSuspended(); if (mIsSuspended != suspended) { mIsSuspended = suspended; boolean newSuspendedState = false; // Data can only be (temporarily) suspended while data is in active state if (getCurrentState() == mActiveState) { // Never set suspended for emergency apn. Emergency data connection // can work while device is not in service. if (mApnSetting != null && mApnSetting.isEmergencyApn()) { newSuspendedState = false; // If we are not in service, change to suspended. } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) { newSuspendedState = true; // Check voice/data concurrency. } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; } } // Only notify when there is a change. if (mIsSuspended != newSuspendedState) { mIsSuspended = newSuspendedState; // If data connection is active, we need to notify the new data connection state // changed event. // changed event reflecting the latest suspended state. if (isActive()) { notifyDataConnectionState(); } Loading Loading @@ -2921,6 +2919,11 @@ public class DataConnection extends StateMachine { mDisabledApnTypeBitMask |= getDisallowedApnTypes(); updateLinkPropertiesHttpProxy(); // The suspended state is only meaningful when data is in active state. We need to // make sure the suspended state is correct as soon as we enter active state. // After this, the network agent will be created with the correct suspended state // (i.e. NOT_SUSPENDED capability). updateSuspendState(); mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore, configBuilder.build(), provider, mTransportType); Loading Loading @@ -3941,7 +3944,7 @@ public class DataConnection extends StateMachine { return TelephonyManager.DATA_CONNECTING; } else if (isActive()) { // The data connection can only be suspended when it's in active state. if (isSuspended()) { if (mIsSuspended) { return TelephonyManager.DATA_SUSPENDED; } return TelephonyManager.DATA_CONNECTED; Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java +24 −6 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ import android.telephony.AccessNetworkConstants; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.telephony.ServiceState.RegState; import android.telephony.ServiceState.RilRadioTechnology; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.DataProfile; Loading @@ -63,6 +65,7 @@ import android.telephony.data.DataServiceCallback; import android.telephony.data.TrafficDescriptor; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; import com.android.internal.R; import com.android.internal.telephony.PhoneConstants; Loading Loading @@ -429,9 +432,9 @@ public class DataConnectionTest extends TelephonyTest { } private boolean isSuspended() throws Exception { Method method = DataConnection.class.getDeclaredMethod("isSuspended"); method.setAccessible(true); return (boolean) method.invoke(mDc); Field field = DataConnection.class.getDeclaredField("mIsSuspended"); field.setAccessible(true); return field.getBoolean(mDc); } private SetupResult setLinkProperties(DataCallResponse response, LinkProperties linkProperties) Loading Loading @@ -926,6 +929,12 @@ public class DataConnectionTest extends TelephonyTest { assertTrue(mDc.isInactive()); } private void serviceStateChangedEvent(@RegState int dataRegState, @RilRadioTechnology int rat) { mDc.obtainMessage(DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, new AsyncResult(null, new Pair<>(dataRegState, rat), null)).sendToTarget(); waitForMs(100); } @Test @SmallTest public void testIsIpAddress() { Loading Loading @@ -1281,24 +1290,33 @@ public class DataConnectionTest extends TelephonyTest { assertTrue(mDc.isInactive()); doReturn(mApn1).when(mApnContext).getApnSetting(); doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask(); doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed(); connectEvent(true); // Before getting any service state event, the connection should not be suspended. assertFalse(isSuspended()); // Return true if combined reg state is not in service doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getDataRegistrationState(); serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE, ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN); assertTrue(isSuspended()); // Return false if in service and concurrent voice and data is allowed doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getDataRegistrationState(); doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed(); serviceStateChangedEvent(ServiceState.STATE_IN_SERVICE, ServiceState.RIL_RADIO_TECHNOLOGY_LTE); assertFalse(isSuspended()); // Return false if in service and concurrent voice/data not allowed but call state is idle doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed(); doReturn(PhoneConstants.State.IDLE).when(mCT).getState(); mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED); waitForMs(100); assertFalse(isSuspended()); // Return true if in service, concurrent voice/data not allowed, and call state not idle doReturn(PhoneConstants.State.RINGING).when(mCT).getState(); mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED); waitForMs(100); assertTrue(isSuspended()); } Loading