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

Commit e64fc6ec authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Merge "Reset data retry with more scenarios" into tm-dev am: 7fb4ef16

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/17168141

Change-Id: If95d41317636ee38a63c9aee7493bc8f38923461
parents eb507e49 7fb4ef16
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -546,6 +546,13 @@ public class DataNetworkController extends Handler {
         * capable.
         */
        public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {}

        /**
         * Called when data service is bound.
         *
         * @param transport The transport of the data service.
         */
        public void onDataServiceBound(@TransportType int transport) {}
    }

    /**
@@ -2342,7 +2349,8 @@ public class DataNetworkController extends Handler {
                }
            }
        } else {
            mDataRetryManager.reset();
            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                    () -> callback.onDataServiceBound(transport)));
        }
        mDataServiceBound.put(transport, bound);
    }
+107 −16
Original line number Diff line number Diff line
@@ -43,7 +43,9 @@ import android.util.LocalLog;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
import com.android.telephony.Rlog;
@@ -76,20 +78,61 @@ public class DataRetryManager extends Handler {
    /** Event for data handover retry. */
    private static final int EVENT_DATA_HANDOVER_RETRY = 4;

    /** Event for cancelling all data retries and throttling entries. */
    private static final int EVENT_RESET = 5;

    /** Event for data profile/apn unthrottled. */
    private static final int EVENT_DATA_PROFILE_UNTHROTTLED = 6;

    /** Event for cancelling pending handover retry. */
    private static final int EVENT_CANCEL_PENDING_HANDOVER_RETRY = 7;

    /**
     * Event for radio on. This can happen when airplane mode is turned off, or RIL crashes and came
     * back online.
     */
    private static final int EVENT_RADIO_ON = 8;

    /** Event for modem reset. */
    private static final int EVENT_MODEM_RESET = 9;

    /** The maximum entries to preserve. */
    private static final int MAXIMUM_HISTORICAL_ENTRIES = 100;

    @IntDef(prefix = {"RESET_REASON_"},
            value = {
                    RESET_REASON_DATA_PROFILES_CHANGED,
                    RESET_REASON_RADIO_ON,
                    RESET_REASON_MODEM_RESTART,
                    RESET_REASON_DATA_SERVICE_BOUND,
            })
    public @interface RetryResetReason {}

    /** Reset due to data profiles changed. */
    public static final int RESET_REASON_DATA_PROFILES_CHANGED = 1;

    /** Reset due to radio on. This could happen after airplane mode off or RIL restarted. */
    public static final int RESET_REASON_RADIO_ON = 2;

    /** Reset due to modem restarted. */
    public static final int RESET_REASON_MODEM_RESTART = 3;

    /**
     * Reset due to data service bound. This could happen when reboot or when data service crashed
     * and rebound.
     */
    public static final int RESET_REASON_DATA_SERVICE_BOUND = 4;

    /** Reset due to data config changed. */
    public static final int RESET_REASON_DATA_CONFIG_CHANGED = 5;

    /** The phone instance. */
    private final @NonNull Phone mPhone;

    /** The RIL instance. */
    private final @NonNull CommandsInterface mRil;

    /** Logging tag. */
    private final @NonNull String mLogTag;

    /** Local log. */
    private final @NonNull LocalLog mLocalLog = new LocalLog(128);

    /**
@@ -872,6 +915,7 @@ public class DataRetryManager extends Handler {
            @NonNull Looper looper, @NonNull DataRetryManagerCallback dataRetryManagerCallback) {
        super(looper);
        mPhone = phone;
        mRil = phone.mCi;
        mLogTag = "DRM-" + mPhone.getPhoneId();
        mDataRetryManagerCallbacks.add(dataRetryManagerCallback);

@@ -889,9 +933,18 @@ public class DataRetryManager extends Handler {
        mDataProfileManager.registerCallback(new DataProfileManagerCallback(this::post) {
            @Override
            public void onDataProfilesChanged() {
                onReset();
                onReset(RESET_REASON_DATA_PROFILES_CHANGED);
            }
        });
        dataNetworkController.registerDataNetworkControllerCallback(
                new DataNetworkControllerCallback(this::post) {
                    @Override
                    public void onDataServiceBound() {
                        onReset(RESET_REASON_DATA_SERVICE_BOUND);
                    }
                });
        mRil.registerForOn(this, EVENT_RADIO_ON, null);
        mRil.registerForModemReset(this, EVENT_MODEM_RESET, null);
    }

    @Override
@@ -917,8 +970,11 @@ public class DataRetryManager extends Handler {
                    log("Handover was cancelled earlier. " + dataHandoverRetryEntry);
                }
                break;
            case EVENT_RESET:
                onReset();
            case EVENT_RADIO_ON:
                onReset(RESET_REASON_RADIO_ON);
                break;
            case EVENT_MODEM_RESET:
                onReset(RESET_REASON_MODEM_RESTART);
                break;
            case EVENT_DATA_PROFILE_UNTHROTTLED:
                ar = (AsyncResult) msg.obj;
@@ -945,20 +1001,13 @@ public class DataRetryManager extends Handler {
     * Called when data config is updated.
     */
    private void onDataConfigUpdated() {
        reset();
        onReset(RESET_REASON_DATA_CONFIG_CHANGED);
        mDataSetupRetryRuleList = mDataConfigManager.getDataSetupRetryRules();
        mDataHandoverRetryRuleList = mDataConfigManager.getDataHandoverRetryRules();
        log("onDataConfigUpdated: mDataSetupRetryRuleList=" + mDataSetupRetryRuleList
                + ", mDataHandoverRetryRuleList=" + mDataHandoverRetryRuleList);
    }

    /**
     * Cancel all pending data retries and throttling entries.
     */
    public void reset() {
        sendMessageAtFrontOfQueue(obtainMessage(EVENT_RESET));
    }

    /**
     * Evaluate if data setup retry is needed or not. If needed, retry will be scheduled
     * automatically after evaluation.
@@ -1145,13 +1194,32 @@ public class DataRetryManager extends Handler {
    }

    /** Cancel all retries and throttling entries. */
    private void onReset() {
        logl("Remove all retry and throttling entries.");
    private void onReset(@RetryResetReason int reason) {
        logl("Remove all retry and throttling entries, reason=" + resetReasonToString(reason));
        removeMessages(EVENT_DATA_SETUP_RETRY);
        removeMessages(EVENT_DATA_HANDOVER_RETRY);
        mDataRetryEntries.stream()
                .filter(entry -> entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED)
                .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));

        final List<ThrottleStatus> throttleStatusList = new ArrayList<>();
        for (DataThrottlingEntry dataThrottlingEntry : mDataThrottlingEntries) {
            throttleStatusList.addAll(dataThrottlingEntry.dataProfile.getApnSetting().getApnTypes()
                    .stream()
                    .map(apnType -> new ThrottleStatus.Builder()
                            .setApnType(apnType)
                            .setSlotIndex(mPhone.getPhoneId())
                            .setNoThrottle()
                            .setRetryType(dataThrottlingEntry.retryType)
                            .setTransportType(dataThrottlingEntry.transport)
                            .build())
                    .collect(Collectors.toList()));
        }
        if (!throttleStatusList.isEmpty()) {
            mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                    () -> callback.onThrottleStatusChanged(throttleStatusList)));
        }

        mDataThrottlingEntries.clear();
    }

@@ -1476,6 +1544,29 @@ public class DataRetryManager extends Handler {
        mDataRetryManagerCallbacks.remove(callback);
    }

    /**
     * Convert reset reason to string
     *
     * @param reason The reason
     * @return The reason in string format.
     */
    private static @NonNull String resetReasonToString(int reason) {
        switch (reason) {
            case RESET_REASON_DATA_PROFILES_CHANGED:
                return "DATA_PROFILES_CHANGED";
            case RESET_REASON_RADIO_ON:
                return "RADIO_ON";
            case RESET_REASON_MODEM_RESTART:
                return "MODEM_RESTART";
            case RESET_REASON_DATA_SERVICE_BOUND:
                return "DATA_SERVICE_BOUND";
            case RESET_REASON_DATA_CONFIG_CHANGED:
                return "DATA_CONFIG_CHANGED";
            default:
                return "UNKNOWN(" + reason + ")";
        }
    }

    /**
     * Log debug messages.
     * @param s debug messages
+50 −0
Original line number Diff line number Diff line
@@ -624,4 +624,54 @@ public class DataRetryManagerTest extends TelephonyTest {
                .build(), mPhone);
        assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr)).isTrue();
    }

    @Test
    public void testRilCrashedReset() {
        testDataSetupRetryNetworkSuggestedNeverRetry();
        Mockito.clearInvocations(mDataRetryManagerCallbackMock);

        // RIL crashed and came back online.
        mDataRetryManagerUT.obtainMessage(8/*EVENT_RADIO_ON*/,
                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
                .sendToTarget();
        processAllMessages();

        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
                ArgumentCaptor.forClass(List.class);
        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
                throttleStatusCaptor.capture());
        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
        assertThat(throttleStatus.getRetryType())
                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1);
        assertThat(throttleStatus.getTransportType())
                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
    }

    @Test
    public void testModemCrashedReset() {
        testDataSetupRetryNetworkSuggestedNeverRetry();
        Mockito.clearInvocations(mDataRetryManagerCallbackMock);

        // RIL crashed and came back online.
        mDataRetryManagerUT.obtainMessage(9/*EVENT_MODEM_RESET*/,
                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
                .sendToTarget();
        processAllMessages();

        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
                ArgumentCaptor.forClass(List.class);
        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
                throttleStatusCaptor.capture());
        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
        assertThat(throttleStatus.getRetryType())
                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1);
        assertThat(throttleStatus.getTransportType())
                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
    }
}