Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +34 −15 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public class DataStallRecoveryManager extends Handler { value = { RECOVERY_ACTION_GET_DATA_CALL_LIST, RECOVERY_ACTION_CLEANUP, RECOVERY_ACTION_REREGISTER, RECOVERY_ACTION_RADIO_RESTART, RECOVERY_ACTION_RESET_MODEM }) Loading @@ -82,16 +83,25 @@ public class DataStallRecoveryManager extends Handler { */ public static final int RECOVERY_ACTION_CLEANUP = 1; // TODO: b/214662910: Align the recovery action between DataStallRecoveryManager and Westworld. /** * Add the RECOVERY_ACTION_REREGISTER to align the RecoveryActions between * DataStallRecoveryManager and Westworld. In Android T, This action will not process because * the boolean array for skip recovery action is default true in carrier config setting. * * @deprecated Do not use. */ @java.lang.Deprecated public static final int RECOVERY_ACTION_REREGISTER = 2; /* DataStallRecoveryManager will request ServiceStateTracker to send RIL_REQUEST_RADIO_POWER * to restart radio. It will restart the radio and re-attch to the network. */ public static final int RECOVERY_ACTION_RADIO_RESTART = 2; public static final int RECOVERY_ACTION_RADIO_RESTART = 3; /* DataStallRecoveryManager will request to reboot modem using NV_RESET_CONFIG. It will recover * if there is a problem in modem side. */ public static final int RECOVERY_ACTION_RESET_MODEM = 3; public static final int RECOVERY_ACTION_RESET_MODEM = 4; /** Recovered reason taken in case of data stall recovered */ @IntDef( Loading Loading @@ -158,6 +168,8 @@ public class DataStallRecoveryManager extends Handler { private boolean mRadioStateChangedDuringDataStall; /** Whether mobile data change to Enabled during data stall. */ private boolean mMobileDataChangedToEnabledDuringDataStall; /** Whether attempted all recovery steps. */ private boolean mIsAttemptedAllSteps; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; Loading Loading @@ -334,8 +346,8 @@ public class DataStallRecoveryManager extends Handler { mIsValidNetwork = true; cancelNetworkCheckTimer(); resetAction(); mIsAttemptedAllSteps = false; } else { if (mIsValidNetwork || isRecoveryAlreadyStarted()) { mIsValidNetwork = false; if (isRecoveryNeeded()) { log("trigger data stall recovery"); Loading @@ -344,7 +356,6 @@ public class DataStallRecoveryManager extends Handler { } } } } /** Reset the action to initial step. */ private void resetAction() { Loading Loading @@ -501,7 +512,7 @@ public class DataStallRecoveryManager extends Handler { logv("enter: isRecoveryNeeded()"); // Skip recovery if we have already attempted all steps. if (mLastAction == RECOVERY_ACTION_RESET_MODEM) { if (mIsAttemptedAllSteps && mLastAction == RECOVERY_ACTION_RESET_MODEM) { logl("skip retrying continue recovery action"); return false; } Loading Loading @@ -575,16 +586,22 @@ public class DataStallRecoveryManager extends Handler { * * @param isValid true for validation passed & false for validation failed */ @RecoveredReason private int getRecoveredReason(boolean isValid) { if (!isValid) return RECOVERED_REASON_NONE; int ret = RECOVERED_REASON_DSRM; if (mRadioStateChangedDuringDataStall) { return RECOVERED_REASON_MODEM; if (mLastAction <= RECOVERY_ACTION_CLEANUP) { ret = RECOVERED_REASON_MODEM; } if (mLastAction > RECOVERY_ACTION_CLEANUP) { ret = RECOVERED_REASON_DSRM; } } else if (mMobileDataChangedToEnabledDuringDataStall) { return RECOVERED_REASON_USER; } else { return RECOVERED_REASON_DSRM; ret = RECOVERED_REASON_USER; } return ret; } /** Perform a series of data stall recovery actions. */ Loading Loading @@ -631,6 +648,7 @@ public class DataStallRecoveryManager extends Handler { logl("doRecovery(): modem reset"); rebootModem(); resetAction(); mIsAttemptedAllSteps = true; break; default: throw new RuntimeException( Loading Loading @@ -755,6 +773,7 @@ public class DataStallRecoveryManager extends Handler { pw.println("mIsValidNetwork=" + mIsValidNetwork); pw.println("mDataStalled=" + mDataStalled); pw.println("mLastAction=" + recoveryActionToString(mLastAction)); pw.println("mIsAttemptedAllSteps=" + mIsAttemptedAllSteps); pw.println("mDataStallStartMs=" + DataUtils.elapsedTimeToString(mDataStallStartMs)); pw.println("mRadioPowerState=" + radioPowerStateToString(mRadioPowerState)); pw.println("mLastActionReported=" + mLastActionReported); Loading tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +11 −11 Original line number Diff line number Diff line Loading @@ -58,8 +58,8 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { super.setUp(getClass().getSimpleName()); mDataStallRecoveryManagerCallback = mock(DataStallRecoveryManagerCallback.class); mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class); long[] dataStallRecoveryTimersArray = new long[] {100, 100, 100}; boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, false, false}; long[] dataStallRecoveryTimersArray = new long[] {100, 100, 100, 100}; boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, true, false, false}; doReturn(dataStallRecoveryTimersArray) .when(mDataConfigManager) .getDataStallRecoveryDelayMillis(); Loading Loading @@ -118,7 +118,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testRecoveryStepRestartRadio() throws Exception { mDataStallRecoveryManager.setRecoveryAction(2); mDataStallRecoveryManager.setRecoveryAction(3); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); Loading @@ -131,7 +131,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testRecoveryStepModemReset() throws Exception { mDataStallRecoveryManager.setRecoveryAction(3); mDataStallRecoveryManager.setRecoveryAction(4); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); Loading @@ -145,7 +145,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testDoNotDoRecoveryActionWhenPoorSignal() throws Exception { mDataStallRecoveryManager.setRecoveryAction(2); mDataStallRecoveryManager.setRecoveryAction(3); doReturn(1).when(mSignalStrength).getLevel(); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); Loading @@ -160,7 +160,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testDoNotDoRecoveryActionWhenDialCall() throws Exception { mDataStallRecoveryManager.setRecoveryAction(2); mDataStallRecoveryManager.setRecoveryAction(3); doReturn(3).when(mSignalStrength).getLevel(); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.OFFHOOK).when(mPhone).getState(); Loading @@ -170,7 +170,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(2); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test Loading @@ -185,11 +185,11 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { processAllMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); mDataStallRecoveryManager.sendMessageDelayed( mDataStallRecoveryManager.obtainMessage(2), 1000); mDataStallRecoveryManager.obtainMessage(3), 1000); moveTimeForward(15000); processAllMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(2); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test Loading @@ -210,12 +210,12 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(2); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(4); // Handle multiple VALIDATION_STATUS_NOT_VALID and make sure we don't attempt recovery for (int i = 0; i < 4; i++) { Loading Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +34 −15 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public class DataStallRecoveryManager extends Handler { value = { RECOVERY_ACTION_GET_DATA_CALL_LIST, RECOVERY_ACTION_CLEANUP, RECOVERY_ACTION_REREGISTER, RECOVERY_ACTION_RADIO_RESTART, RECOVERY_ACTION_RESET_MODEM }) Loading @@ -82,16 +83,25 @@ public class DataStallRecoveryManager extends Handler { */ public static final int RECOVERY_ACTION_CLEANUP = 1; // TODO: b/214662910: Align the recovery action between DataStallRecoveryManager and Westworld. /** * Add the RECOVERY_ACTION_REREGISTER to align the RecoveryActions between * DataStallRecoveryManager and Westworld. In Android T, This action will not process because * the boolean array for skip recovery action is default true in carrier config setting. * * @deprecated Do not use. */ @java.lang.Deprecated public static final int RECOVERY_ACTION_REREGISTER = 2; /* DataStallRecoveryManager will request ServiceStateTracker to send RIL_REQUEST_RADIO_POWER * to restart radio. It will restart the radio and re-attch to the network. */ public static final int RECOVERY_ACTION_RADIO_RESTART = 2; public static final int RECOVERY_ACTION_RADIO_RESTART = 3; /* DataStallRecoveryManager will request to reboot modem using NV_RESET_CONFIG. It will recover * if there is a problem in modem side. */ public static final int RECOVERY_ACTION_RESET_MODEM = 3; public static final int RECOVERY_ACTION_RESET_MODEM = 4; /** Recovered reason taken in case of data stall recovered */ @IntDef( Loading Loading @@ -158,6 +168,8 @@ public class DataStallRecoveryManager extends Handler { private boolean mRadioStateChangedDuringDataStall; /** Whether mobile data change to Enabled during data stall. */ private boolean mMobileDataChangedToEnabledDuringDataStall; /** Whether attempted all recovery steps. */ private boolean mIsAttemptedAllSteps; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; Loading Loading @@ -334,8 +346,8 @@ public class DataStallRecoveryManager extends Handler { mIsValidNetwork = true; cancelNetworkCheckTimer(); resetAction(); mIsAttemptedAllSteps = false; } else { if (mIsValidNetwork || isRecoveryAlreadyStarted()) { mIsValidNetwork = false; if (isRecoveryNeeded()) { log("trigger data stall recovery"); Loading @@ -344,7 +356,6 @@ public class DataStallRecoveryManager extends Handler { } } } } /** Reset the action to initial step. */ private void resetAction() { Loading Loading @@ -501,7 +512,7 @@ public class DataStallRecoveryManager extends Handler { logv("enter: isRecoveryNeeded()"); // Skip recovery if we have already attempted all steps. if (mLastAction == RECOVERY_ACTION_RESET_MODEM) { if (mIsAttemptedAllSteps && mLastAction == RECOVERY_ACTION_RESET_MODEM) { logl("skip retrying continue recovery action"); return false; } Loading Loading @@ -575,16 +586,22 @@ public class DataStallRecoveryManager extends Handler { * * @param isValid true for validation passed & false for validation failed */ @RecoveredReason private int getRecoveredReason(boolean isValid) { if (!isValid) return RECOVERED_REASON_NONE; int ret = RECOVERED_REASON_DSRM; if (mRadioStateChangedDuringDataStall) { return RECOVERED_REASON_MODEM; if (mLastAction <= RECOVERY_ACTION_CLEANUP) { ret = RECOVERED_REASON_MODEM; } if (mLastAction > RECOVERY_ACTION_CLEANUP) { ret = RECOVERED_REASON_DSRM; } } else if (mMobileDataChangedToEnabledDuringDataStall) { return RECOVERED_REASON_USER; } else { return RECOVERED_REASON_DSRM; ret = RECOVERED_REASON_USER; } return ret; } /** Perform a series of data stall recovery actions. */ Loading Loading @@ -631,6 +648,7 @@ public class DataStallRecoveryManager extends Handler { logl("doRecovery(): modem reset"); rebootModem(); resetAction(); mIsAttemptedAllSteps = true; break; default: throw new RuntimeException( Loading Loading @@ -755,6 +773,7 @@ public class DataStallRecoveryManager extends Handler { pw.println("mIsValidNetwork=" + mIsValidNetwork); pw.println("mDataStalled=" + mDataStalled); pw.println("mLastAction=" + recoveryActionToString(mLastAction)); pw.println("mIsAttemptedAllSteps=" + mIsAttemptedAllSteps); pw.println("mDataStallStartMs=" + DataUtils.elapsedTimeToString(mDataStallStartMs)); pw.println("mRadioPowerState=" + radioPowerStateToString(mRadioPowerState)); pw.println("mLastActionReported=" + mLastActionReported); Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +11 −11 Original line number Diff line number Diff line Loading @@ -58,8 +58,8 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { super.setUp(getClass().getSimpleName()); mDataStallRecoveryManagerCallback = mock(DataStallRecoveryManagerCallback.class); mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class); long[] dataStallRecoveryTimersArray = new long[] {100, 100, 100}; boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, false, false}; long[] dataStallRecoveryTimersArray = new long[] {100, 100, 100, 100}; boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, true, false, false}; doReturn(dataStallRecoveryTimersArray) .when(mDataConfigManager) .getDataStallRecoveryDelayMillis(); Loading Loading @@ -118,7 +118,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testRecoveryStepRestartRadio() throws Exception { mDataStallRecoveryManager.setRecoveryAction(2); mDataStallRecoveryManager.setRecoveryAction(3); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); Loading @@ -131,7 +131,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testRecoveryStepModemReset() throws Exception { mDataStallRecoveryManager.setRecoveryAction(3); mDataStallRecoveryManager.setRecoveryAction(4); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); Loading @@ -145,7 +145,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testDoNotDoRecoveryActionWhenPoorSignal() throws Exception { mDataStallRecoveryManager.setRecoveryAction(2); mDataStallRecoveryManager.setRecoveryAction(3); doReturn(1).when(mSignalStrength).getLevel(); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); Loading @@ -160,7 +160,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { @Test public void testDoNotDoRecoveryActionWhenDialCall() throws Exception { mDataStallRecoveryManager.setRecoveryAction(2); mDataStallRecoveryManager.setRecoveryAction(3); doReturn(3).when(mSignalStrength).getLevel(); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.OFFHOOK).when(mPhone).getState(); Loading @@ -170,7 +170,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { processAllFutureMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(2); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test Loading @@ -185,11 +185,11 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { processAllMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1); mDataStallRecoveryManager.sendMessageDelayed( mDataStallRecoveryManager.obtainMessage(2), 1000); mDataStallRecoveryManager.obtainMessage(3), 1000); moveTimeForward(15000); processAllMessages(); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(2); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); } @Test Loading @@ -210,12 +210,12 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(2); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllMessages(); moveTimeForward(101); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3); assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(4); // Handle multiple VALIDATION_STATUS_NOT_VALID and make sure we don't attempt recovery for (int i = 0; i < 4; i++) { Loading