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

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

Merge changes from topic "permanent_failure_cause" am: 9f4eac9e

parents 8113e140 9f4eac9e
Loading
Loading
Loading
Loading
+45 −21
Original line number Diff line number Diff line
@@ -195,50 +195,74 @@ public class DataEvaluation {
    @VisibleForTesting
    public enum DataEvaluationReason {
        /** New request from the apps. */
        NEW_REQUEST,
        NEW_REQUEST(false),
        /** Data config changed. */
        DATA_CONFIG_CHANGED,
        DATA_CONFIG_CHANGED(true),
        /** SIM is loaded. */
        SIM_LOADED,
        SIM_LOADED(true),
        /** SIM is removed. */
        SIM_REMOVAL,
        SIM_REMOVAL(true),
        /** Data profiles changed. */
        DATA_PROFILES_CHANGED,
        DATA_PROFILES_CHANGED(true),
        /** When service state changes.(For now only considering data RAT and data registration). */
        DATA_SERVICE_STATE_CHANGED,
        DATA_SERVICE_STATE_CHANGED(true),
        /** When data is enabled or disabled (by user, carrier, thermal, etc...) */
        DATA_ENABLED_CHANGED,
        DATA_ENABLED_CHANGED(true),
        /** When data enabled overrides are changed (MMS always allowed, data on non-DDS sub). */
        DATA_ENABLED_OVERRIDE_CHANGED,
        DATA_ENABLED_OVERRIDE_CHANGED(true),
        /** When data roaming is enabled or disabled. */
        ROAMING_ENABLED_CHANGED,
        ROAMING_ENABLED_CHANGED(true),
        /** When voice call ended (for concurrent voice/data not supported RAT). */
        VOICE_CALL_ENDED,
        VOICE_CALL_ENDED(true),
        /** When network restricts or no longer restricts mobile data. */
        DATA_RESTRICTED_CHANGED,
        DATA_RESTRICTED_CHANGED(true),
        /** Network capabilities changed. The unsatisfied requests might have chances to attach. */
        DATA_NETWORK_CAPABILITIES_CHANGED,
        DATA_NETWORK_CAPABILITIES_CHANGED(true),
        /** When emergency call started or ended. */
        EMERGENCY_CALL_CHANGED,
        EMERGENCY_CALL_CHANGED(true),
        /** When data disconnected, re-evaluate later to see if data could be brought up again. */
        RETRY_AFTER_DISCONNECTED,
        RETRY_AFTER_DISCONNECTED(true),
        /** Data setup retry. */
        DATA_RETRY,
        DATA_RETRY(false),
        /** For handover evaluation, or for network tearing down after handover succeeds/fails. */
        DATA_HANDOVER,
        DATA_HANDOVER(true),
        /** Preferred transport changed. */
        PREFERRED_TRANSPORT_CHANGED,
        PREFERRED_TRANSPORT_CHANGED(true),
        /** Slice config changed. */
        SLICE_CONFIG_CHANGED,
        SLICE_CONFIG_CHANGED(true),
        /**
         * Single data network arbitration. On certain RATs, only one data network is allowed at the
         * same time.
         */
        SINGLE_DATA_NETWORK_ARBITRATION,
        SINGLE_DATA_NETWORK_ARBITRATION(true),
        /** Query from {@link TelephonyManager#isDataConnectivityPossible()}. */
        EXTERNAL_QUERY,
        EXTERNAL_QUERY(false),
        /** Tracking area code changed. */
        TAC_CHANGED,
        TAC_CHANGED(true);

        /**
         * {@code true} if the evaluation is due to environmental changes (i.e. SIM removal,
         * registration state changes, etc....
         */
        private final boolean mIsConditionBased;

        /**
         * @return {@code true} if the evaluation is due to environmental changes (i.e. SIM removal,
         * registration state changes, etc....
         */
        public boolean isConditionBased() {
            return mIsConditionBased;
        }

        /**
         * Constructor
         *
         * @param isConditionBased {@code true} if the evaluation is due to environmental changes
         * (i.e. SIM removal, registration state changes, etc....)
         */
        DataEvaluationReason(boolean isConditionBased) {
            mIsConditionBased = isConditionBased;
        }
    }

    /** Disallowed reasons. There could be multiple reasons if it is not allowed. */
+1 −1
Original line number Diff line number Diff line
@@ -3161,7 +3161,7 @@ public class DataNetwork extends StateMachine {
                && !mAttachedNetworkRequestList.isEmpty()) {
            TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0);
            DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
                    .getDataProfileForNetworkRequest(networkRequest, targetNetworkType);
                    .getDataProfileForNetworkRequest(networkRequest, targetNetworkType, true);
            // Some carriers have different profiles between cellular and IWLAN. We need to
            // dynamically switch profile, but only when those profiles have same APN name.
            if (dataProfile != null && dataProfile.getApnSetting() != null
+19 −2
Original line number Diff line number Diff line
@@ -551,6 +551,15 @@ public class DataNetworkController extends Handler {
         */
        public void onInternetDataNetworkConnected(@NonNull List<DataProfile> dataProfiles) {}

        /**
         * Called when data network is connected.
         *
         * @param transport Transport for the connected network.
         * @param dataProfile The data profile of the connected data network.
         */
        public void onDataNetworkConnected(@TransportType int transport,
                @NonNull DataProfile dataProfile) {}

        /** Called when internet data network is disconnected. */
        public void onInternetDataNetworkDisconnected() {}

@@ -1426,7 +1435,7 @@ public class DataNetworkController extends Handler {
        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
            evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
            evaluation.setCandidateDataProfile(mDataProfileManager.getDataProfileForNetworkRequest(
                    networkRequest, getDataNetworkType(transport)));
                    networkRequest, getDataNetworkType(transport), true));
            networkRequest.setEvaluation(evaluation);
            log(evaluation.toString());
            return evaluation;
@@ -1575,7 +1584,10 @@ public class DataNetworkController extends Handler {
            networkType = mServiceState.getVoiceNetworkType();
        }
        DataProfile dataProfile = mDataProfileManager
                .getDataProfileForNetworkRequest(networkRequest, networkType);
                .getDataProfileForNetworkRequest(networkRequest, networkType,
                        // If the evaluation is due to environmental changes, then we should ignore
                        // the permanent failure reached earlier.
                        reason.isConditionBased());
        if (dataProfile == null) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.NO_SUITABLE_DATA_PROFILE);
        } else if (reason == DataEvaluationReason.NEW_REQUEST
@@ -2602,6 +2614,11 @@ public class DataNetworkController extends Handler {
     */
    private void onDataNetworkConnected(@NonNull DataNetwork dataNetwork) {
        logl("onDataNetworkConnected: " + dataNetwork);

        mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                () -> callback.onDataNetworkConnected(dataNetwork.getTransport(),
                        dataNetwork.getDataProfile())));

        mPreviousConnectedDataNetworkList.add(0, dataNetwork);
        // Preserve the connected data networks for debugging purposes.
        if (mPreviousConnectedDataNetworkList.size() > MAX_HISTORICAL_CONNECTED_DATA_NETWORKS) {
+27 −4
Original line number Diff line number Diff line
@@ -621,14 +621,18 @@ public class DataProfileManager extends Handler {
     *
     * @param networkRequest The network request.
     * @param networkType The current data network type.
     * @param ignorePermanentFailure {@code true} to ignore {@link ApnSetting#getPermanentFailed()}.
     * This should be set to true for condition-based retry/setup.
     * @return The data profile. {@code null} if can't find any satisfiable data profile.
     */
    public @Nullable DataProfile getDataProfileForNetworkRequest(
            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType) {
            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
            boolean ignorePermanentFailure) {
        ApnSetting apnSetting = null;
        if (networkRequest.hasAttribute(TelephonyNetworkRequest
                .CAPABILITY_ATTRIBUTE_APN_SETTING)) {
            apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType);
            apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType,
                    ignorePermanentFailure);
        }

        TrafficDescriptor.Builder trafficDescriptorBuilder = new TrafficDescriptor.Builder();
@@ -687,10 +691,13 @@ public class DataProfileManager extends Handler {
     *
     * @param networkRequest The network request.
     * @param networkType The current data network type.
     * @param ignorePermanentFailure {@code true} to ignore {@link ApnSetting#getPermanentFailed()}.
     * This should be set to true for condition-based retry/setup.
     * @return The APN setting. {@code null} if can't find any satisfiable data profile.
     */
    private @Nullable ApnSetting getApnSettingForNetworkRequest(
            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType) {
            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
            boolean ignorePermanentFailure) {
        if (!networkRequest.hasAttribute(
                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
            loge("Network request does not have APN setting attribute.");
@@ -733,6 +740,7 @@ public class DataProfileManager extends Handler {
                        && (dp.getApnSetting().getApnSetId()
                        == Telephony.Carriers.MATCH_ALL_APN_SET_ID
                        || dp.getApnSetting().getApnSetId() == mPreferredDataProfileSetId))
                .filter(dp -> ignorePermanentFailure || !dp.getApnSetting().getPermanentFailed())
                .collect(Collectors.toList());
        if (dataProfiles.size() == 0) {
            log("Can't find any data profile has APN set id matched. mPreferredDataProfileSetId="
@@ -740,6 +748,15 @@ public class DataProfileManager extends Handler {
            return null;
        }

        // Check if data profiles are permanently failed.
        dataProfiles = dataProfiles.stream()
                .filter(dp -> ignorePermanentFailure || !dp.getApnSetting().getPermanentFailed())
                .collect(Collectors.toList());
        if (dataProfiles.size() == 0) {
            log("The suitable data profiles are all in permanent failed state.");
            return null;
        }

        return dataProfiles.get(0).getApnSetting();
    }

@@ -772,7 +789,7 @@ public class DataProfileManager extends Handler {
                new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
                        .build(), mPhone);
        return getDataProfileForNetworkRequest(networkRequest, networkType) != null;
        return getDataProfileForNetworkRequest(networkRequest, networkType, true) != null;
    }

     /**
@@ -1094,6 +1111,12 @@ public class DataProfileManager extends Handler {
        pw.println("Initial attach data profile=" + mInitialAttachDataProfile);
        pw.println("isTetheringDataProfileExisting=" + isTetheringDataProfileExisting(
                TelephonyManager.NETWORK_TYPE_LTE));
        pw.println("Permanent failed profiles=");
        pw.increaseIndent();
        mAllDataProfiles.stream()
                .filter(dp -> dp.getApnSetting() != null && dp.getApnSetting().getPermanentFailed())
                .forEach(pw::println);
        pw.decreaseIndent();

        pw.println("Local logs:");
        pw.increaseIndent();
+170 −88
Original line number Diff line number Diff line
@@ -56,7 +56,6 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -315,10 +314,6 @@ public class DataRetryManager extends Handler {
                }
            }

            if (mMaxRetries == 0) {
                mRetryIntervalsMillis = Collections.emptyList();
            }

            if (mMaxRetries < 0) {
                throw new IllegalArgumentException("Max retries should not be less than 0. "
                        + "mMaxRetries=" + mMaxRetries);
@@ -359,39 +354,45 @@ public class DataRetryManager extends Handler {
    }

    /**
     * Represent a setup data network retry rule.
     * Represent a rule for data setup retry.
     *
     * The syntax of the retry rule:
     * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network
     * capabilities are supported.
     * "capabilities=[netCaps1|netCaps2|...], [retry_interval=n1|n2|n3|n4...],
     * [maximum_retries=n]"
     * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network capabilities
     *    are supported. If the capabilities are not specified, then the retry rule only applies
     *    to the current failed APN used in setup data call request.
     * "capabilities=[netCaps1|netCaps2|...], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
     *
     * 2. Retry based on {@link DataFailCause}
     * "fail_causes=[cause1|cause2|cause3|..], [retry_interval=n1|n2|n3|n4...],
     * [maximum_retries=n]"
     * "fail_causes=[cause1|cause2|cause3|..], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
     *
     * 3. Retry based on {@link NetworkCapabilities} and {@link DataFailCause}. Note that only
     *    APN-type network capabilities are supported.
     * "capabilities=[netCaps1|netCaps2|...], fail_causes=[cause1|cause2|cause3|...],
     *     [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
     *
     * 4. Permanent fail causes (no timer-based retry) on the current failed APN. Retry interval
     *    is specified for retrying the next available APN.
     * "permanent_fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|65543|65547|
     *     2252|2253|2254, retry_interval=2500"
     *
     * For example,
     * "capabilities=eims, retry_interval=1000, maximum_retries=20" means if the attached
     * network request is emergency, then retry data network setup every 1 second for up to 20
     * times.
     *
     * "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|2254
     * , maximum_retries=0" means for those fail causes, never retry with timers. Note that
     * when environment changes, retry can still happen.
     *
     * "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|"
     * "5000|10000|15000|20000|40000|60000|120000|240000|600000|1200000|1800000"
     * "1800000, maximum_retries=20" means for those capabilities, retry happens in 2.5s, 3s,
     * 5s, 10s, 15s, 20s, 40s, 1m, 2m, 4m, 10m, 20m, 30m, 30m, 30m, until reaching 20 retries.
     * "1800000, maximum_retries=20" means for those capabilities, retry happens in 2.5s, 3s, 5s,
     * 10s, 15s, 20s, 40s, 1m, 2m, 4m, 10m, 20m, 30m, 30m, 30m, until reaching 20 retries.
     *
     */
    public static class DataSetupRetryRule extends DataRetryRule {
        private static final String RULE_TAG_PERMANENT_FAIL_CAUSES = "permanent_fail_causes";
        private static final String RULE_TAG_CAPABILITIES = "capabilities";

        /** {@code true} if this rule is for permanent fail causes. */
        private boolean mIsPermanentFailCauseRule;

        /**
         * Constructor
         *
@@ -410,8 +411,23 @@ public class DataRetryManager extends Handler {
                }
                String key = tokens[0].trim();
                String value = tokens[1].trim();
                if (key.equals(RULE_TAG_CAPABILITIES)) {
                    mNetworkCapabilities = DataUtils.getNetworkCapabilitiesFromString(value);
                try {
                    switch (key) {
                        case RULE_TAG_PERMANENT_FAIL_CAUSES:
                            mFailCauses = Arrays.stream(value.split("\\s*\\|\\s*"))
                                    .map(String::trim)
                                    .map(Integer::valueOf)
                                    .collect(Collectors.toSet());
                            mIsPermanentFailCauseRule = true;
                            break;
                        case RULE_TAG_CAPABILITIES:
                            mNetworkCapabilities = DataUtils
                                    .getNetworkCapabilitiesFromString(value);
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new IllegalArgumentException("illegal rule " + ruleString + ", e=" + e);
                }
            }

@@ -433,6 +449,13 @@ public class DataRetryManager extends Handler {
            return mNetworkCapabilities;
        }

        /**
         * @return {@code true} if this rule is for permanent fail causes.
         */
        public boolean isPermanentFailCauseRule() {
            return mIsPermanentFailCauseRule;
        }

        /**
         * Check if this rule can be matched.
         *
@@ -949,10 +972,27 @@ public class DataRetryManager extends Handler {
        });
        dataNetworkController.registerDataNetworkControllerCallback(
                new DataNetworkControllerCallback(this::post) {
                    /**
                     * Called when data service is bound.
                     *
                     * @param transport The transport of the data service.
                     */
                    @Override
                    public void onDataServiceBound(@TransportType int transport) {
                        onReset(RESET_REASON_DATA_SERVICE_BOUND);
                    }

                    /**
                     * Called when data network is connected.
                     *
                     * @param transport Transport for the connected network.
                     * @param dataProfile The data profile of the connected data network.
                     */
                    @Override
                    public void onDataNetworkConnected(@TransportType int transport,
                            @NonNull DataProfile dataProfile) {
                        DataRetryManager.this.onDataNetworkConnected(transport, dataProfile);
                    }
                });
        mRil.registerForOn(this, EVENT_RADIO_ON, null);
        mRil.registerForModemReset(this, EVENT_MODEM_RESET, null);
@@ -1001,7 +1041,7 @@ public class DataRetryManager extends Handler {
                } else if (ar.result instanceof DataProfile) {
                    dataProfile = (DataProfile) ar.result;
                }
                onDataProfileUnthrottled(dataProfile, apn, transport, true);
                onDataProfileUnthrottled(dataProfile, apn, transport, true, true);
                break;
            case EVENT_CANCEL_PENDING_HANDOVER_RETRY:
                onCancelPendingHandoverRetry((DataNetwork) msg.obj);
@@ -1034,6 +1074,21 @@ public class DataRetryManager extends Handler {
                + ", mDataHandoverRetryRuleList=" + mDataHandoverRetryRuleList);
    }

    /**
     * Called when data network is connected.
     *
     * @param transport Transport for the connected network.
     * @param dataProfile The data profile of the connected data network.
     */
    public void onDataNetworkConnected(@TransportType int transport,
            @NonNull DataProfile dataProfile) {
        if (dataProfile.getApnSetting() != null) {
            dataProfile.getApnSetting().setPermanentFailed(false);
        }

        onDataProfileUnthrottled(dataProfile, null, transport, true, false);
    }

    /**
     * Evaluate if data setup retry is needed or not. If needed, retry will be scheduled
     * automatically after evaluation.
@@ -1072,6 +1127,7 @@ public class DataRetryManager extends Handler {
            // ThrottleStatus is just for API backwards compatibility reason.
            updateThrottleStatus(dataProfile, requestList, null,
                    ThrottleStatus.RETRY_TYPE_NEW_CONNECTION, transport, Long.MAX_VALUE);
            return;
        } else if (retryDelayMillis != DataCallResponse.RETRY_DURATION_UNDEFINED) {
            // Network specifically asks retry the previous data profile again.
            DataSetupRetryEntry dataSetupRetryEntry = new DataSetupRetryEntry.Builder<>()
@@ -1085,23 +1141,46 @@ public class DataRetryManager extends Handler {
                    ThrottleStatus.RETRY_TYPE_NEW_CONNECTION, transport,
                    dataSetupRetryEntry.retryElapsedTime);
            schedule(dataSetupRetryEntry);
        } else {
            // Network did not suggest any retry. Use the configured rules to perform retry.
            logv("mDataSetupRetryRuleList=" + mDataSetupRetryRuleList);

            // Support the legacy permanent failure configuration
            if (DataFailCause.isPermanentFailure(mPhone.getContext(), cause, mPhone.getSubId())) {
                log("Stopped timer-based retry. cause=" + DataFailCause.toString(cause));
            return;
        }

        // Network did not suggest any retry. Use the configured rules to perform retry.
        logv("mDataSetupRetryRuleList=" + mDataSetupRetryRuleList);

        boolean retryScheduled = false;
        List<NetworkRequestList> groupedNetworkRequestLists =
                DataUtils.getGroupedNetworkRequestList(requestList);
        for (DataSetupRetryRule retryRule : mDataSetupRetryRuleList) {
            if (retryRule.isPermanentFailCauseRule() && retryRule.getFailCauses().contains(cause)) {
                if (dataProfile.getApnSetting() != null) {
                    dataProfile.getApnSetting().setPermanentFailed(true);

                    // It seems strange to have retry timer in permanent failure rule, but since
                    // in this case permanent failure is only applicable to the failed profile, so
                    // we need to see if other profile can be selected for next data setup.
                    log("Marked " + dataProfile.getApnSetting().getApnName() + " permanently "
                            + "failed, but still schedule retry to see if another data profile "
                            + "can be used for setup data.");
                    // Schedule a data retry to see if another data profile could be selected.
                    // If the same data profile is selected again, since it's marked as
                    // permanent failure, it won't be used for setup data call.
                    schedule(new DataSetupRetryEntry.Builder<>()
                            .setRetryDelay(retryRule.getRetryIntervalsMillis().get(0))
                            .setAppliedRetryRule(retryRule)
                            .setSetupRetryType(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS)
                            .setTransport(transport)
                            .setNetworkRequestList(requestList)
                            .build());
                } else {
                    // For TD-based data profile, do not do anything for now. Should expand this in
                    // the future if needed.
                    log("Stopped timer-based retry for TD-based data profile. Will retry only when "
                            + "environment changes.");
                }
                return;
            }
            for (NetworkRequestList networkRequestList : groupedNetworkRequestLists) {
                int capability = networkRequestList.get(0).getApnTypeNetworkCapability();

                for (DataSetupRetryRule retryRule : mDataSetupRetryRuleList) {
                if (retryRule.canBeMatched(capability, cause)) {
                    // Check if there is already a similar network request retry scheduled.
                    if (isSimilarNetworkRequestRetryScheduled(
@@ -1147,7 +1226,6 @@ public class DataRetryManager extends Handler {
                    + "retry.");
        }
    }
    }

    /**
     * Evaluate if data handover retry is needed or not. If needed, retry will be scheduled
@@ -1234,7 +1312,7 @@ public class DataRetryManager extends Handler {
            DataProfile dataProfile = dataThrottlingEntry.dataProfile;
            String apn = dataProfile.getApnSetting() != null
                    ? dataProfile.getApnSetting().getApnName() : null;
            onDataProfileUnthrottled(dataProfile, apn, dataThrottlingEntry.transport, false);
            onDataProfileUnthrottled(dataProfile, apn, dataThrottlingEntry.transport, false, true);
        }

        mDataThrottlingEntries.clear();
@@ -1393,9 +1471,10 @@ 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.
     */
    private void onDataProfileUnthrottled(@Nullable DataProfile dataProfile, @Nullable String apn,
            @TransportType int transport, boolean remove) {
            @TransportType int transport, boolean remove, boolean retry) {
        log("onDataProfileUnthrottled: data profile=" + dataProfile + ", apn=" + apn
                + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)
                + ", remove=" + remove);
@@ -1412,6 +1491,7 @@ public class DataRetryManager extends Handler {
            Stream<DataThrottlingEntry> stream = mDataThrottlingEntries.stream();
            stream = stream.filter(entry -> entry.expirationTimeMillis > now);
            if (dataProfile.getApnSetting() != null) {
                dataProfile.getApnSetting().setPermanentFailed(false);
                stream = stream
                        .filter(entry -> entry.dataProfile.getApnSetting() != null)
                        .filter(entry -> entry.dataProfile.getApnSetting().getApnName()
@@ -1473,6 +1553,7 @@ public class DataRetryManager extends Handler {

        logl("onDataProfileUnthrottled: Removing the following throttling entries. "
                + dataUnthrottlingEntries);
        if (retry) {
            for (DataThrottlingEntry entry : dataUnthrottlingEntries) {
                // Immediately retry after unthrottling.
                if (entry.retryType == ThrottleStatus.RETRY_TYPE_NEW_CONNECTION) {
@@ -1490,6 +1571,7 @@ public class DataRetryManager extends Handler {
                            .build());
                }
            }
        }
        if (remove) {
            mDataThrottlingEntries.removeAll(dataUnthrottlingEntries);
        }
Loading