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

Commit 827a7c1b authored by Willy Hu's avatar Willy Hu
Browse files

[DSRM] Fix issues

- Skip recovery action when no service.
  The symptom is: Device in DSDS mode, preferred data on slot0,
  and dial the call on slot1, the data service on slot0 will tmp
  no service, we will skip do recovery action in this case.
- Do not reset action when poor signal/no service

Bug: 228416166
BUg: 224404062
Test: Build pass
      atest DataStallRecoveryManagerTest
Change-Id: Ia6f2ed58f73fa4d96b8bafee8bd22933a99926dd
parent 7b443de6
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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));
@@ -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.
@@ -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;
        }
@@ -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;
        }

@@ -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;
@@ -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);
+55 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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 {
@@ -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();
@@ -83,6 +87,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {
                        mMockedWwanDataServiceManager,
                        mTestableLooper.getLooper(),
                        mDataStallRecoveryManagerCallback);
        sendOnInternetDataNetworkCallback(true);
        logd("DataStallRecoveryManagerTest -Setup!");
    }

@@ -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);
@@ -155,7 +178,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {

        processAllFutureMessages();

        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
    }

    @Test
@@ -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);
    }
}