Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +17 −11 Original line number Diff line number Diff line Loading @@ -151,6 +151,8 @@ public class DataStallRecoveryManager extends Handler { private @ElapsedRealtimeLong long mTimeLastRecoveryStartMs; /** Whether current network is good or not */ private boolean mIsValidNetwork; /** Whether data stall recovery is triggered or not */ private boolean mRecoveryTriggered = false; /** Whether data stall happened or not. */ private boolean mDataStalled; /** Whether the result of last action(RADIO_RESTART) reported. */ Loading Loading @@ -353,6 +355,7 @@ public class DataStallRecoveryManager extends Handler { */ private void reset() { mIsValidNetwork = true; mRecoveryTriggered = false; mIsAttemptedAllSteps = false; mRadioStateChangedDuringDataStall = false; mIsAirPlaneModeEnableDuringDataStall = false; Loading @@ -374,17 +377,14 @@ public class DataStallRecoveryManager extends Handler { setNetworkValidationState(isValid); if (isValid) { reset(); } else { if (mIsValidNetwork || isRecoveryAlreadyStarted()) { } else if (isRecoveryNeeded(true)) { // Set the network as invalid, because recovery is needed mIsValidNetwork = false; if (isRecoveryNeeded(true)) { log("trigger data stall recovery"); mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime(); sendMessage(obtainMessage(EVENT_DO_RECOVERY)); } } } } /** Reset the action to initial step. */ private void resetAction() { Loading Loading @@ -456,7 +456,7 @@ public class DataStallRecoveryManager extends Handler { * @return {@code true} if recovery already started, {@code false} recovery not started. */ private boolean isRecoveryAlreadyStarted() { return getRecoveryAction() != RECOVERY_ACTION_GET_DATA_CALL_LIST; return getRecoveryAction() != RECOVERY_ACTION_GET_DATA_CALL_LIST || mRecoveryTriggered; } /** Loading Loading @@ -543,6 +543,12 @@ public class DataStallRecoveryManager extends Handler { private boolean isRecoveryNeeded(boolean isNeedToCheckTimer) { logv("enter: isRecoveryNeeded()"); // Skip if network is invalid and recovery was not started yet if (!mIsValidNetwork && !isRecoveryAlreadyStarted()) { logl("skip when network still remains invalid and recovery was not started yet"); return false; } // Skip recovery if we have already attempted all steps. if (mIsAttemptedAllSteps) { logl("skip retrying continue recovery action"); Loading Loading @@ -578,7 +584,6 @@ public class DataStallRecoveryManager extends Handler { logl("skip data stall recovery as data not connected"); return false; } return true; } Loading Loading @@ -671,6 +676,7 @@ public class DataStallRecoveryManager extends Handler { private void doRecovery() { @RecoveryAction final int recoveryAction = getRecoveryAction(); final int signalStrength = mPhone.getSignalStrength().getLevel(); mRecoveryTriggered = true; // 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. Loading tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +48 −0 Original line number Diff line number Diff line Loading @@ -351,6 +351,54 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { } } @Test public void testNextRecoveryAfterSkippingUnderPoorSignal() throws Exception { // Test to validate if the next recovery action is performed in good signal // soon after skipping the recovery action under poor signal condition sendOnInternetDataNetworkCallback(true); mDataStallRecoveryManager.setRecoveryAction(1); doReturn(1).when(mSignalStrength).getLevel(); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); // verify skipping recovery action under poor signal condition assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); // Set the signal condition to good doReturn(3).when(mSignalStrength).getLevel(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); // verify next recovery action is performed under good signal condition assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test public void testDoNotRecoveryForAlwaysInvalidNetwork() throws Exception { // Test to verify that recovery action is not performed for always invalid network // In some lab testing scenarios, n/w validation always remain invalid. sendOnInternetDataNetworkCallback(false); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); mDataStallRecoveryManager .setRecoveryAction(DataStallRecoveryManager.RECOVERY_ACTION_GET_DATA_CALL_LIST); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); moveTimeForward(101); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); } @Test public void testStartTimeNotZero() throws Exception { sendOnInternetDataNetworkCallback(false); Loading Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +17 −11 Original line number Diff line number Diff line Loading @@ -151,6 +151,8 @@ public class DataStallRecoveryManager extends Handler { private @ElapsedRealtimeLong long mTimeLastRecoveryStartMs; /** Whether current network is good or not */ private boolean mIsValidNetwork; /** Whether data stall recovery is triggered or not */ private boolean mRecoveryTriggered = false; /** Whether data stall happened or not. */ private boolean mDataStalled; /** Whether the result of last action(RADIO_RESTART) reported. */ Loading Loading @@ -353,6 +355,7 @@ public class DataStallRecoveryManager extends Handler { */ private void reset() { mIsValidNetwork = true; mRecoveryTriggered = false; mIsAttemptedAllSteps = false; mRadioStateChangedDuringDataStall = false; mIsAirPlaneModeEnableDuringDataStall = false; Loading @@ -374,17 +377,14 @@ public class DataStallRecoveryManager extends Handler { setNetworkValidationState(isValid); if (isValid) { reset(); } else { if (mIsValidNetwork || isRecoveryAlreadyStarted()) { } else if (isRecoveryNeeded(true)) { // Set the network as invalid, because recovery is needed mIsValidNetwork = false; if (isRecoveryNeeded(true)) { log("trigger data stall recovery"); mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime(); sendMessage(obtainMessage(EVENT_DO_RECOVERY)); } } } } /** Reset the action to initial step. */ private void resetAction() { Loading Loading @@ -456,7 +456,7 @@ public class DataStallRecoveryManager extends Handler { * @return {@code true} if recovery already started, {@code false} recovery not started. */ private boolean isRecoveryAlreadyStarted() { return getRecoveryAction() != RECOVERY_ACTION_GET_DATA_CALL_LIST; return getRecoveryAction() != RECOVERY_ACTION_GET_DATA_CALL_LIST || mRecoveryTriggered; } /** Loading Loading @@ -543,6 +543,12 @@ public class DataStallRecoveryManager extends Handler { private boolean isRecoveryNeeded(boolean isNeedToCheckTimer) { logv("enter: isRecoveryNeeded()"); // Skip if network is invalid and recovery was not started yet if (!mIsValidNetwork && !isRecoveryAlreadyStarted()) { logl("skip when network still remains invalid and recovery was not started yet"); return false; } // Skip recovery if we have already attempted all steps. if (mIsAttemptedAllSteps) { logl("skip retrying continue recovery action"); Loading Loading @@ -578,7 +584,6 @@ public class DataStallRecoveryManager extends Handler { logl("skip data stall recovery as data not connected"); return false; } return true; } Loading Loading @@ -671,6 +676,7 @@ public class DataStallRecoveryManager extends Handler { private void doRecovery() { @RecoveryAction final int recoveryAction = getRecoveryAction(); final int signalStrength = mPhone.getSignalStrength().getLevel(); mRecoveryTriggered = true; // 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. Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +48 −0 Original line number Diff line number Diff line Loading @@ -351,6 +351,54 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { } } @Test public void testNextRecoveryAfterSkippingUnderPoorSignal() throws Exception { // Test to validate if the next recovery action is performed in good signal // soon after skipping the recovery action under poor signal condition sendOnInternetDataNetworkCallback(true); mDataStallRecoveryManager.setRecoveryAction(1); doReturn(1).when(mSignalStrength).getLevel(); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); // verify skipping recovery action under poor signal condition assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); // Set the signal condition to good doReturn(3).when(mSignalStrength).getLevel(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); // verify next recovery action is performed under good signal condition assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test public void testDoNotRecoveryForAlwaysInvalidNetwork() throws Exception { // Test to verify that recovery action is not performed for always invalid network // In some lab testing scenarios, n/w validation always remain invalid. sendOnInternetDataNetworkCallback(false); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); mDataStallRecoveryManager .setRecoveryAction(DataStallRecoveryManager.RECOVERY_ACTION_GET_DATA_CALL_LIST); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); moveTimeForward(101); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); } @Test public void testStartTimeNotZero() throws Exception { sendOnInternetDataNetworkCallback(false); Loading