Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 996d4624 authored by Willy Hu's avatar Willy Hu
Browse files

[DSRM] Fix the index ArrayIndexOutOfBoundsException

Symptom:
- java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
- This issue will happen when device meet data stall and recovered by
  RECOVERY_ACTION_MODEM_RESET, the validation status should be (Failed -> Passed -> Failed),
  When device meet the data stall again, since the lastaction keep
  RESET_MODEM(index 4) so we meet the IndexOutOfBoundsException.

Solution:
- We will initialize all parameters when we receiving the validation passed.
BUg: 222418674
Test: atest DataStallRecoveryManagerTest
      test result: go/dsrm-test-result

Change-Id: I41e3102997f9e4e25b1120c63e6526b0e7a6b06c
parent 7552567f
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -337,6 +337,20 @@ public class DataStallRecoveryManager extends Handler {
        }
    }

    /**
     * Called when internet validation status passed. We will initialize all parameters.
     */
    private void reset() {
        mIsValidNetwork = true;
        mIsAttemptedAllSteps = false;
        mRadioStateChangedDuringDataStall = false;
        mMobileDataChangedToEnabledDuringDataStall = false;
        cancelNetworkCheckTimer();
        mTimeLastRecoveryStartMs = 0;
        mLastAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
        mRecovryAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
    }

    /**
     * Called when internet validation status changed.
     *
@@ -347,10 +361,7 @@ public class DataStallRecoveryManager extends Handler {
        final boolean isValid = status == NetworkAgent.VALIDATION_STATUS_VALID;
        setNetworkValidationState(isValid);
        if (isValid) {
            mIsValidNetwork = true;
            cancelNetworkCheckTimer();
            resetAction();
            mIsAttemptedAllSteps = false;
            reset();
        } else {
            mIsValidNetwork = false;
            if (isRecoveryNeeded(true)) {
@@ -518,7 +529,7 @@ public class DataStallRecoveryManager extends Handler {
        logv("enter: isRecoveryNeeded()");

        // Skip recovery if we have already attempted all steps.
        if (mIsAttemptedAllSteps && mLastAction == RECOVERY_ACTION_RESET_MODEM) {
        if (mIsAttemptedAllSteps) {
            logl("skip retrying continue recovery action");
            return false;
        }
+44 −0
Original line number Diff line number Diff line
@@ -250,6 +250,50 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {
        }
    }

    @Test
    public void testDoRecoveryWhenMeetDataStallAgain() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        mDataStallRecoveryManager.setRecoveryAction(0);
        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
        doReturn(3).when(mSignalStrength).getLevel();
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
        logd("Sending validation failed callback");

        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
        processAllMessages();
        moveTimeForward(101);
        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);

        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
        processAllMessages();
        moveTimeForward(101);
        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);

        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
        processAllMessages();
        moveTimeForward(101);
        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++) {
            sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
            logd("Sending validation failed callback");
            processAllMessages();
            moveTimeForward(101);
            assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
        }

        moveTimeForward(101);
        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);

        mDataStallRecoveryManager.sendMessageDelayed(
                mDataStallRecoveryManager.obtainMessage(0), 1000);
        processAllMessages();
        processAllMessages();
        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
    }

    @Test
    public void testDoNotDoRecoveryWhenDataNoService() throws Exception {
        mDataStallRecoveryManager.setRecoveryAction(1);