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

Commit dac5e8a1 authored by Ling Ma's avatar Ling Ma
Browse files

Don't clear throttling when network disconnects

Before the change, the throttle entries are cleared without notifying onThrottleStatusChanged via callback. Because the decision of unthrotting should only be made by modem, the fix keeps the throttle status even when network disconnects.

Also removed isAnySetupRetryScheduled(). The method in fact only checks for modem demanded retry, which is already covered by isDataProfileThrottled().

Fix: 254480678
Test: placed voice call + internet browsing
Change-Id: Id52f036fb006286411dfc53690f6b5c36e635649
parent d5210a5d
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -1618,13 +1618,11 @@ public class DataNetworkController extends Handler {
                        reason.isConditionBased());
        if (dataProfile == null) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.NO_SUITABLE_DATA_PROFILE);
        } else if (reason == DataEvaluationReason.NEW_REQUEST
                && (mDataRetryManager.isAnySetupRetryScheduled(dataProfile, transport)
                || mDataRetryManager.isSimilarNetworkRequestRetryScheduled(
                        networkRequest, transport))) {
            // If this is a new request, check if there is any retry already scheduled. For all
            // other evaluation reasons, since they are all condition changes, so if there is any
            // retry scheduled, we still want to go ahead and setup the data network.
        } else if (// Check for new requests if we already self-scheduled(as opposed to modem
            // demanded) retry for similar requests.
                reason == DataEvaluationReason.NEW_REQUEST
                        &&  mDataRetryManager.isSimilarNetworkRequestRetryScheduled(
                        networkRequest, transport)) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.RETRY_SCHEDULED);
        } else if (mDataRetryManager.isDataProfileThrottled(dataProfile, transport)) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED);
+13 −28
Original line number Diff line number Diff line
@@ -1427,15 +1427,20 @@ public class DataRetryManager extends Handler {
            @TransportType int transport, @ElapsedRealtimeLong long expirationTime) {
        DataThrottlingEntry entry = new DataThrottlingEntry(dataProfile, networkRequestList,
                dataNetwork, transport, retryType, expirationTime);
        if (mDataThrottlingEntries.size() >= MAXIMUM_HISTORICAL_ENTRIES) {
            mDataThrottlingEntries.remove(0);
        }

        // Remove previous entry that contains the same data profile.
        // Remove previous entry that contains the same data profile. Therefore it should always
        // contain at maximum all the distinct data profiles of the current subscription.
        mDataThrottlingEntries.removeIf(
                throttlingEntry -> dataProfile.equals(throttlingEntry.dataProfile));


        if (mDataThrottlingEntries.size() >= MAXIMUM_HISTORICAL_ENTRIES) {
            // If we don't see the anomaly report after U release, we should remove this check for
            // the commented reason above.
            AnomalyReporter.reportAnomaly(
                    UUID.fromString("24fd4d46-1d0f-4b13-b7d6-7bad70b8289b"),
                    "DataRetryManager throttling more than 100 data profiles",
                    mPhone.getCarrierId());
            mDataThrottlingEntries.remove(0);
        }
        logl("Add throttling entry " + entry);
        mDataThrottlingEntries.add(entry);

@@ -1470,11 +1475,11 @@ public class DataRetryManager extends Handler {
     * When this is set, {@code dataProfile} must be {@code null}.
     * @param transport The transport that this unthrottling request is on.
     * @param remove Whether to remove unthrottled entries from the list of entries.
     * @param retry Whether schedule data setup retry after unthrottling.
     * @param retry Whether schedule retry after unthrottling.
     */
    private void onDataProfileUnthrottled(@Nullable DataProfile dataProfile, @Nullable String apn,
            @TransportType int transport, boolean remove, boolean retry) {
        log("onDataProfileUnthrottled: data profile=" + dataProfile + ", apn=" + apn
        log("onDataProfileUnthrottled: dataProfile=" + dataProfile + ", apn=" + apn
                + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)
                + ", remove=" + remove);

@@ -1486,7 +1491,6 @@ public class DataRetryManager extends Handler {
            // equal to the data profiles kept in data profile manager (due to some fields missing
            // in DataProfileInfo.aidl), so we need to get the equivalent data profile from data
            // profile manager.
            log("onDataProfileUnthrottled: dataProfile=" + dataProfile);
            Stream<DataThrottlingEntry> stream = mDataThrottlingEntries.stream();
            stream = stream.filter(entry -> entry.expirationTimeMillis > now);
            if (dataProfile.getApnSetting() != null) {
@@ -1641,23 +1645,6 @@ public class DataRetryManager extends Handler {
        return false;
    }

    /**
     * Check if there is any data setup retry scheduled with specified data profile.
     *
     * @param dataProfile The data profile to retry.
     * @param transport The transport that the request is on.
     * @return {@code true} if there is retry scheduled for this data profile.
     */
    public boolean isAnySetupRetryScheduled(@NonNull DataProfile dataProfile,
            @TransportType int transport) {
        return mDataRetryEntries.stream()
                .filter(DataSetupRetryEntry.class::isInstance)
                .map(DataSetupRetryEntry.class::cast)
                .anyMatch(entry -> entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED
                        && dataProfile.equals(entry.dataProfile)
                        && entry.transport == transport);
    }

    /**
     * Check if a specific data profile is explicitly throttled by the network.
     *
@@ -1693,13 +1680,11 @@ public class DataRetryManager extends Handler {
                        && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork
                        && entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED)
                .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
        mDataThrottlingEntries.removeIf(entry -> entry.dataNetwork == dataNetwork);
    }

    /**
     * Check if there is any data handover retry scheduled.
     *
     *
     * @param dataNetwork The network network to retry handover.
     * @return {@code true} if there is retry scheduled for this network capability.
     */
+31 −2
Original line number Diff line number Diff line
@@ -2769,7 +2769,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        processAllFutureMessages();

        // TAC changes should clear the already-scheduled retry and throttling.
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isAnySetupRetryScheduled(
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
                mImsCellularDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();

        // But DNC should re-evaluate unsatisfied request and setup IMS again.
@@ -2873,6 +2873,35 @@ public class DataNetworkControllerTest extends TelephonyTest {
                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
    }

    @Test
    public void testHandoverDataNetworkNetworkSuggestedRetryTimerDataThrottled() throws Exception {
        testSetupImsDataNetwork();

        DataNetwork network = getDataNetworks().get(0);
        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
                DataFailCause.HANDOVER_FAILED, 10000, true);
        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);

        // Verify retry scheduled on this network
        assertThat(mDataNetworkControllerUT.getDataRetryManager()
                .isAnyHandoverRetryScheduled(network)).isTrue();
        // Verify the data profile is throttled on WLAN
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
                network.getDataProfile(), AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).isTrue();

        // Test even if network disconnected, the throttle status should remain
        network.tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
        processAllFutureMessages();

        // Verify retry is cleared on this network
        assertThat(mDataNetworkControllerUT.getDataRetryManager()
                .isAnyHandoverRetryScheduled(network)).isFalse();
        // Verify the data profile is still throttled
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
                network.getDataProfile(), AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).isTrue();
    }

    @Test
    public void testTacChangesClearThrottlingAndRetryHappens() throws Exception {
        testSetupDataNetworkNetworkSuggestedRetryTimerDataThrottled();
@@ -2886,7 +2915,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
        processAllFutureMessages();

        // TAC changes should clear the already-scheduled retry and throttling.
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isAnySetupRetryScheduled(
        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
                mImsCellularDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();

        // But DNC should re-evaluate unsatisfied request and setup IMS again.