Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +24 −10 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ public class DataStallRecoveryManager extends Handler { private boolean mMobileDataChangedToEnabledDuringDataStall; /** Whether attempted all recovery steps. */ private boolean mIsAttemptedAllSteps; /** Whether internet network connected. */ private boolean mIsInternetNetworkConnected; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; Loading Loading @@ -254,12 +256,14 @@ public class DataStallRecoveryManager extends Handler { @Override public void onInternetDataNetworkConnected( @NonNull List<DataProfile> dataProfiles) { // onInternetNetworkConnected(); mIsInternetNetworkConnected = true; logl("onInternetDataNetworkConnected"); } @Override public void onInternetDataNetworkDisconnected() { // onInternetNetworkDisconnected(); mIsInternetNetworkConnected = false; logl("onInternetDataNetworkDisconnected"); } }); mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); Loading Loading @@ -349,7 +353,7 @@ public class DataStallRecoveryManager extends Handler { mIsAttemptedAllSteps = false; } else { mIsValidNetwork = false; if (isRecoveryNeeded()) { if (isRecoveryNeeded(true)) { log("trigger data stall recovery"); mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime(); sendMessage(obtainMessage(EVENT_DO_RECOVERY)); Loading Loading @@ -505,10 +509,12 @@ public class DataStallRecoveryManager extends Handler { /** * Check the conditions if we need to do recovery action. * * @param isNeedToCheckTimer {@code true} indicating we need the check timer when * we receive the internet validation status changed. * @return {@code true} if need to do recovery action, {@code false} no need to do recovery * action. */ private boolean isRecoveryNeeded() { private boolean isRecoveryNeeded(boolean isNeedToCheckTimer) { logv("enter: isRecoveryNeeded()"); // Skip recovery if we have already attempted all steps. Loading @@ -518,7 +524,8 @@ public class DataStallRecoveryManager extends Handler { } // To avoid back to back recovery, wait for a grace period if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction)) { if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction) && isNeedToCheckTimer) { logl("skip back to back data stall recovery"); return false; } Loading @@ -533,7 +540,16 @@ public class DataStallRecoveryManager extends Handler { // Skip when poor signal strength if (mPhone.getSignalStrength().getLevel() <= CellSignalStrength.SIGNAL_STRENGTH_POOR) { logl("skip data stall recovery as in poor signal condition"); resetAction(); return false; } if (!mDataNetworkController.isInternetDataAllowed()) { logl("skip data stall recovery as data not allowed."); return false; } if (!mIsInternetNetworkConnected) { logl("skip data stall recovery as data not connected"); return false; } Loading Loading @@ -611,10 +627,7 @@ public class DataStallRecoveryManager extends Handler { // DSRM used sendMessageDelayed to process the next event EVENT_DO_RECOVERY, so it need // to check the condition if DSRM need to process the recovery action. // Skip recovery if it can cause a call to drop if (mPhone.getState() != PhoneConstants.State.IDLE && getRecoveryAction() > RECOVERY_ACTION_CLEANUP) { logl("skip data stall recovery as there is an active call"); if (!isRecoveryNeeded(false)) { cancelNetworkCheckTimer(); startNetworkCheckTimer(recoveryAction); return; Loading Loading @@ -771,6 +784,7 @@ public class DataStallRecoveryManager extends Handler { pw.increaseIndent(); pw.println("mIsValidNetwork=" + mIsValidNetwork); pw.println("mIsInternetNetworkConnected=" + mIsInternetNetworkConnected); pw.println("mDataStalled=" + mDataStalled); pw.println("mLastAction=" + recoveryActionToString(mLastAction)); pw.println("mIsAttemptedAllSteps=" + mIsAttemptedAllSteps); Loading tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +55 −4 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.internal.telephony.data; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; Loading @@ -31,11 +29,13 @@ import static org.mockito.Mockito.verify; import android.net.NetworkAgent; import android.telephony.Annotation.ValidationStatus; import android.telephony.CarrierConfigManager; import android.telephony.data.DataProfile; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback; import org.junit.After; Loading @@ -44,6 +44,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.List; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class DataStallRecoveryManagerTest extends TelephonyTest { Loading @@ -66,7 +69,8 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { doReturn(dataStallRecoveryStepsArray) .when(mDataConfigManager) .getDataStallRecoveryShouldSkipArray(); doReturn(mSST).when(mPhone).getServiceStateTracker(); doReturn(true).when(mDataNetworkController).isInternetDataAllowed(); doAnswer( invocation -> { ((Runnable) invocation.getArguments()[0]).run(); Loading @@ -83,6 +87,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { mMockedWwanDataServiceManager, mTestableLooper.getLooper(), mDataStallRecoveryManagerCallback); sendOnInternetDataNetworkCallback(true); logd("DataStallRecoveryManagerTest -Setup!"); } Loading @@ -103,6 +108,24 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { dataNetworkControllerCallback.onInternetDataNetworkValidationStatusChanged(status); } private void sendOnInternetDataNetworkCallback(boolean isConnected) { ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor = ArgumentCaptor.forClass(DataNetworkControllerCallback.class); verify(mDataNetworkController) .registerDataNetworkControllerCallback( dataNetworkControllerCallbackCaptor.capture()); DataNetworkControllerCallback dataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue(); if (isConnected) { List<DataProfile> dataprofile = new ArrayList<DataProfile>(); dataNetworkControllerCallback.onInternetDataNetworkConnected(dataprofile); } else { dataNetworkControllerCallback.onInternetDataNetworkDisconnected(); } processAllMessages(); } @Test public void testRecoveryStepPDPReset() throws Exception { mDataStallRecoveryManager.setRecoveryAction(1); Loading Loading @@ -155,7 +178,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test Loading Loading @@ -226,4 +249,32 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); } } @Test public void testDoNotDoRecoveryWhenDataNoService() throws Exception { mDataStallRecoveryManager.setRecoveryAction(1); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); doReturn(false).when(mDataNetworkController).isInternetDataAllowed(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); } @Test public void testDoNotDoRecoveryWhenDataNetworkNotConnected() throws Exception { mDataStallRecoveryManager.setRecoveryAction(1); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); sendOnInternetDataNetworkCallback(false); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); } } Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +24 −10 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ public class DataStallRecoveryManager extends Handler { private boolean mMobileDataChangedToEnabledDuringDataStall; /** Whether attempted all recovery steps. */ private boolean mIsAttemptedAllSteps; /** Whether internet network connected. */ private boolean mIsInternetNetworkConnected; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; Loading Loading @@ -254,12 +256,14 @@ public class DataStallRecoveryManager extends Handler { @Override public void onInternetDataNetworkConnected( @NonNull List<DataProfile> dataProfiles) { // onInternetNetworkConnected(); mIsInternetNetworkConnected = true; logl("onInternetDataNetworkConnected"); } @Override public void onInternetDataNetworkDisconnected() { // onInternetNetworkDisconnected(); mIsInternetNetworkConnected = false; logl("onInternetDataNetworkDisconnected"); } }); mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); Loading Loading @@ -349,7 +353,7 @@ public class DataStallRecoveryManager extends Handler { mIsAttemptedAllSteps = false; } else { mIsValidNetwork = false; if (isRecoveryNeeded()) { if (isRecoveryNeeded(true)) { log("trigger data stall recovery"); mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime(); sendMessage(obtainMessage(EVENT_DO_RECOVERY)); Loading Loading @@ -505,10 +509,12 @@ public class DataStallRecoveryManager extends Handler { /** * Check the conditions if we need to do recovery action. * * @param isNeedToCheckTimer {@code true} indicating we need the check timer when * we receive the internet validation status changed. * @return {@code true} if need to do recovery action, {@code false} no need to do recovery * action. */ private boolean isRecoveryNeeded() { private boolean isRecoveryNeeded(boolean isNeedToCheckTimer) { logv("enter: isRecoveryNeeded()"); // Skip recovery if we have already attempted all steps. Loading @@ -518,7 +524,8 @@ public class DataStallRecoveryManager extends Handler { } // To avoid back to back recovery, wait for a grace period if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction)) { if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction) && isNeedToCheckTimer) { logl("skip back to back data stall recovery"); return false; } Loading @@ -533,7 +540,16 @@ public class DataStallRecoveryManager extends Handler { // Skip when poor signal strength if (mPhone.getSignalStrength().getLevel() <= CellSignalStrength.SIGNAL_STRENGTH_POOR) { logl("skip data stall recovery as in poor signal condition"); resetAction(); return false; } if (!mDataNetworkController.isInternetDataAllowed()) { logl("skip data stall recovery as data not allowed."); return false; } if (!mIsInternetNetworkConnected) { logl("skip data stall recovery as data not connected"); return false; } Loading Loading @@ -611,10 +627,7 @@ public class DataStallRecoveryManager extends Handler { // DSRM used sendMessageDelayed to process the next event EVENT_DO_RECOVERY, so it need // to check the condition if DSRM need to process the recovery action. // Skip recovery if it can cause a call to drop if (mPhone.getState() != PhoneConstants.State.IDLE && getRecoveryAction() > RECOVERY_ACTION_CLEANUP) { logl("skip data stall recovery as there is an active call"); if (!isRecoveryNeeded(false)) { cancelNetworkCheckTimer(); startNetworkCheckTimer(recoveryAction); return; Loading Loading @@ -771,6 +784,7 @@ public class DataStallRecoveryManager extends Handler { pw.increaseIndent(); pw.println("mIsValidNetwork=" + mIsValidNetwork); pw.println("mIsInternetNetworkConnected=" + mIsInternetNetworkConnected); pw.println("mDataStalled=" + mDataStalled); pw.println("mLastAction=" + recoveryActionToString(mLastAction)); pw.println("mIsAttemptedAllSteps=" + mIsAttemptedAllSteps); Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +55 −4 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.internal.telephony.data; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; Loading @@ -31,11 +29,13 @@ import static org.mockito.Mockito.verify; import android.net.NetworkAgent; import android.telephony.Annotation.ValidationStatus; import android.telephony.CarrierConfigManager; import android.telephony.data.DataProfile; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback; import org.junit.After; Loading @@ -44,6 +44,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.List; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class DataStallRecoveryManagerTest extends TelephonyTest { Loading @@ -66,7 +69,8 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { doReturn(dataStallRecoveryStepsArray) .when(mDataConfigManager) .getDataStallRecoveryShouldSkipArray(); doReturn(mSST).when(mPhone).getServiceStateTracker(); doReturn(true).when(mDataNetworkController).isInternetDataAllowed(); doAnswer( invocation -> { ((Runnable) invocation.getArguments()[0]).run(); Loading @@ -83,6 +87,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { mMockedWwanDataServiceManager, mTestableLooper.getLooper(), mDataStallRecoveryManagerCallback); sendOnInternetDataNetworkCallback(true); logd("DataStallRecoveryManagerTest -Setup!"); } Loading @@ -103,6 +108,24 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { dataNetworkControllerCallback.onInternetDataNetworkValidationStatusChanged(status); } private void sendOnInternetDataNetworkCallback(boolean isConnected) { ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor = ArgumentCaptor.forClass(DataNetworkControllerCallback.class); verify(mDataNetworkController) .registerDataNetworkControllerCallback( dataNetworkControllerCallbackCaptor.capture()); DataNetworkControllerCallback dataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue(); if (isConnected) { List<DataProfile> dataprofile = new ArrayList<DataProfile>(); dataNetworkControllerCallback.onInternetDataNetworkConnected(dataprofile); } else { dataNetworkControllerCallback.onInternetDataNetworkDisconnected(); } processAllMessages(); } @Test public void testRecoveryStepPDPReset() throws Exception { mDataStallRecoveryManager.setRecoveryAction(1); Loading Loading @@ -155,7 +178,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test Loading Loading @@ -226,4 +249,32 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); } } @Test public void testDoNotDoRecoveryWhenDataNoService() throws Exception { mDataStallRecoveryManager.setRecoveryAction(1); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); doReturn(false).when(mDataNetworkController).isInternetDataAllowed(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); } @Test public void testDoNotDoRecoveryWhenDataNetworkNotConnected() throws Exception { mDataStallRecoveryManager.setRecoveryAction(1); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); sendOnInternetDataNetworkCallback(false); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); } }