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

Commit 2a3b6308 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[DSRM] Fix the unexpected recovery in the LAB" into main

parents 0bf5f4bd 523ed0f6
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -702,6 +702,13 @@ public class DataNetworkController extends Handler {
         * @param qosBearerSessions The latest QOS bearer sessions.
         */
        public void onQosSessionsChanged(@NonNull List<QosBearerSession> qosBearerSessions) {}

        /**
         * Called when the SIM state changed.
         *
         * @param simState The SIM state.
         */
        public void onSimStateChanged(@SimState int simState) {}
    }

    /**
@@ -3591,6 +3598,8 @@ public class DataNetworkController extends Handler {
            mSimState = simState;
            if (simState == TelephonyManager.SIM_STATE_ABSENT) {
                onSimAbsent();
                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                    () -> callback.onSimStateChanged(simState)));
            } else if (simState == TelephonyManager.SIM_STATE_LOADED) {
                sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
                        DataEvaluationReason.SIM_LOADED));
+21 −3
Original line number Diff line number Diff line
@@ -344,6 +344,13 @@ public class DataStallRecoveryManager extends Handler {
                                    : "All InternetDataNetwork Disconnected");
                        }
                    }
                    @Override
                    public void onSimStateChanged(int simState) {
                        if (simState == TelephonyManager.SIM_STATE_ABSENT) {
                            log("SIM state is ABSENT, reset DSRM.");
                            reset(true);
                        }
                    }
                });
        mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);

@@ -549,8 +556,13 @@ public class DataStallRecoveryManager extends Handler {
    /**
     * Called when internet validation status passed. We will initialize all parameters.
     */
    private void reset() {
    private void reset(boolean isSimAbsent) {
        if (isSimAbsent) {
            // state set to never passed due to SIM absent
            mIsValidNetwork = false;
        } else {
            mIsValidNetwork = true;
        }
        mRecoveryTriggered = false;
        mIsAttemptedAllSteps = false;
        mRadioStateChangedDuringDataStall = false;
@@ -578,7 +590,7 @@ public class DataStallRecoveryManager extends Handler {
        if (isValid) {
            // Broadcast intent that data stall recovered.
            broadcastDataStallDetected(mLastAction);
            reset();
            reset(false);
        } else if (isRecoveryNeeded(true)) {
            // Set the network as invalid, because recovery is needed
            mIsValidNetwork = false;
@@ -616,6 +628,12 @@ public class DataStallRecoveryManager extends Handler {
     */
    @VisibleForTesting
    public void setRecoveryAction(@RecoveryAction int action) {
        if (!mIsValidNetwork && !isRecoveryAlreadyStarted()) {
            log(
                    "Skip set recovery action because the network still remains invalid and"
                    + " recovery was not started yet.");
            return;
        }
        // Reset the validation count for action change
        if (mRecoveryAction != action) {
            mActionValidationCount = 0;
+82 −4
Original line number Diff line number Diff line
@@ -47,15 +47,15 @@ import com.android.internal.telephony.data.DataNetworkController.DataNetworkCont
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback;

import java.lang.reflect.Field;
import java.util.Set;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

import java.lang.reflect.Field;
import java.util.Set;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DataStallRecoveryManagerTest extends TelephonyTest {
@@ -183,6 +183,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testRecoveryStepPDPReset() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(1);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
@@ -197,6 +198,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testRecoveryStepRestartRadio() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(3);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
@@ -211,6 +213,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testRecoveryStepModemReset() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(4);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
@@ -226,6 +229,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testDoNotDoRecoveryActionWhenPoorSignal() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(3);
        doReturn(1).when(mSignalStrength).getLevel();
@@ -242,6 +246,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testDoNotDoRecoveryActionWhenDialCall() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(3);
        doReturn(3).when(mSignalStrength).getLevel();
@@ -360,6 +365,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testDoNotDoRecoveryWhenDataNoService() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(1);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
@@ -375,6 +381,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testDoNotDoRecoveryWhenDataNetworkNotConnected() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(1);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
@@ -434,6 +441,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {
    public void testSendDSRMData() throws Exception {
        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);

        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        logd("Set phone status to normal status.");
        sendOnInternetDataNetworkCallback(true);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
@@ -447,7 +455,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {
        processAllFutureMessages();

        logd("Verify that the DataStallRecoveryManager sends the expected intents.");
        verify(mPhone.getContext(), times(3)).sendBroadcast(captorIntent.capture());
        verify(mPhone.getContext(), times(4)).sendBroadcast(captorIntent.capture());
        logd(captorIntent.getAllValues().toString());
        for (int i = 0; i < captorIntent.getAllValues().size(); i++) {
            Intent intent = captorIntent.getAllValues().get(i);
@@ -585,6 +593,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

    @Test
    public void testDoNotDoRecoveryActionWhenActiveCall() throws Exception {
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
        sendOnInternetDataNetworkCallback(true);
        mDataStallRecoveryManager.setRecoveryAction(
                DataStallRecoveryManager.RECOVERY_ACTION_RADIO_RESTART);
@@ -602,4 +611,73 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {
        assertThat(mDataStallRecoveryManager.getRecoveryAction())
                .isEqualTo(DataStallRecoveryManager.RECOVERY_ACTION_RADIO_RESTART);
    }

    // set private boolean field using reflection
    private void setPrivateBooleanField(Object obj, String fieldName, boolean value)
            throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.setBoolean(obj, value);
    }

    // get private boolean field using reflection
    private boolean getPrivateBooleanField(Object obj, String fieldName) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.getBoolean(obj);
    }

    /**
     * Test that setRecoveryAction is skipped if the network is invalid and recovery has not yet
     * started.
     */
    @Test
    public void testSetRecoveryAction_skipWhenInvalidNetworkAndNotStarted() throws Exception {
        // Ensure initial state has recovery not started
        assertThat(mDataStallRecoveryManager.getRecoveryAction())
                .isEqualTo(DataStallRecoveryManager.RECOVERY_ACTION_GET_DATA_CALL_LIST);
        assertThat(getPrivateBooleanField(mDataStallRecoveryManager, "mRecoveryTriggered"))
                .isFalse();

        // set network state to invalid
        setPrivateBooleanField(mDataStallRecoveryManager, "mIsValidNetwork", false);

        mDataStallRecoveryManager.setRecoveryAction(
                DataStallRecoveryManager.RECOVERY_ACTION_CLEANUP);
        processAllMessages();

        // Verify that the recovery action was NOT changed.
        assertThat(mDataStallRecoveryManager.getRecoveryAction())
                .isEqualTo(DataStallRecoveryManager.RECOVERY_ACTION_GET_DATA_CALL_LIST);
    }

    /** Test that the DSRM state is reset when the SIM state changes to ABSENT. */
    @Test
    public void testOnSimStateChanged_absentResetsState() throws Exception {
        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
        verify(mDataNetworkController, times(2))
                .registerDataNetworkControllerCallback(
                        dataNetworkControllerCallbackCaptor.capture());
        DataNetworkControllerCallback callback =
                dataNetworkControllerCallbackCaptor.getAllValues().get(0);
        assertNotNull(callback);

        // Set network to valid initially
        setPrivateBooleanField(mDataStallRecoveryManager, "mIsValidNetwork", true);
        mDataStallRecoveryManager.setRecoveryAction(
                DataStallRecoveryManager.RECOVERY_ACTION_CLEANUP);
        setPrivateBooleanField(mDataStallRecoveryManager, "mRecoveryTriggered", true);
        setPrivateBooleanField(mDataStallRecoveryManager, "mDataStalled", true);
        assertThat(mDataStallRecoveryManager.getRecoveryAction())
                .isEqualTo(DataStallRecoveryManager.RECOVERY_ACTION_CLEANUP);
        assertThat(getPrivateBooleanField(mDataStallRecoveryManager, "mIsValidNetwork")).isTrue();

        // Trigger the onSimStateChanged callback with SIM_STATE_ABSENT
        logd("Simulating SIM_STATE_ABSENT");
        callback.onSimStateChanged(TelephonyManager.SIM_STATE_ABSENT);
        processAllMessages(); // Process messages potentially posted by reset()

        assertThat(getPrivateBooleanField(mDataStallRecoveryManager, "mIsValidNetwork")).isFalse();
    }
}