Loading src/java/com/android/internal/telephony/data/DataNetworkController.java +5 −7 Original line number Diff line number Diff line Loading @@ -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); Loading src/java/com/android/internal/telephony/data/DataRetryManager.java +13 −28 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading @@ -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) { Loading Loading @@ -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. * Loading Loading @@ -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. */ Loading tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +31 −2 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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(); Loading @@ -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. Loading Loading
src/java/com/android/internal/telephony/data/DataNetworkController.java +5 −7 Original line number Diff line number Diff line Loading @@ -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); Loading
src/java/com/android/internal/telephony/data/DataRetryManager.java +13 −28 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading @@ -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) { Loading Loading @@ -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. * Loading Loading @@ -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. */ Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +31 −2 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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(); Loading @@ -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. Loading