From a20843638f7340ce4c5198bdb489b8ef66722f73 Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Mon, 3 Jan 2022 15:55:52 +0100 Subject: [PATCH] Add setting that controls network rate limit The INGRESS_RATE_LIMIT_BYTES_PER_SECOND setting controls the rate limit for internet networks. If set to -1, no rate limit applies. There is one global rate limit that will be applied to all networks with NET_CAPABILITY_INTERNET. Test: atest ConnectivitySettingsManagerTest Bug: 157552970 Change-Id: Ia82aa867686d484ce46734f76d4a48bf864eff84 --- framework/api/module-lib-current.txt | 2 + .../net/ConnectivitySettingsManager.java | 41 +++++++++++++++++++ .../net/ConnectivitySettingsManagerTest.kt | 17 ++++++++ 3 files changed, 60 insertions(+) diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index 5961e722b9..e66039ec36 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -69,6 +69,7 @@ package android.net { method @NonNull public static java.time.Duration getDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration); method public static int getDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, int); method @Nullable public static android.net.ProxyInfo getGlobalProxy(@NonNull android.content.Context); + method public static long getIngressRateLimitInBytesPerSecond(@NonNull android.content.Context); method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean); method @NonNull public static java.util.Set getMobileDataPreferredUids(@NonNull android.content.Context); @@ -89,6 +90,7 @@ package android.net { method public static void setDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration); method public static void setDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, @IntRange(from=0, to=100) int); method public static void setGlobalProxy(@NonNull android.content.Context, @NonNull android.net.ProxyInfo); + method public static void setIngressRateLimitInBytesPerSecond(@NonNull android.content.Context, @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) long); method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean); method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set); diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java index 8fc0065347..4e28b29a85 100644 --- a/framework/src/android/net/ConnectivitySettingsManager.java +++ b/framework/src/android/net/ConnectivitySettingsManager.java @@ -383,6 +383,14 @@ public class ConnectivitySettingsManager { public static final String UIDS_ALLOWED_ON_RESTRICTED_NETWORKS = "uids_allowed_on_restricted_networks"; + /** + * A global rate limit that applies to all networks with NET_CAPABILITY_INTERNET when enabled. + * + * @hide + */ + public static final String INGRESS_RATE_LIMIT_BYTES_PER_SECOND = + "ingress_rate_limit_bytes_per_second"; + /** * Get mobile data activity timeout from {@link Settings}. * @@ -1071,4 +1079,37 @@ public class ConnectivitySettingsManager { Settings.Global.putString(context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS, uids); } + + /** + * Get the global network bandwidth rate limit. + * + * The limit is only applicable to networks that provide internet connectivity. If the setting + * is unset, it defaults to -1. + * + * @param context The {@link Context} to query the setting. + * @return The rate limit in number of bytes per second or -1 if disabled. + */ + public static long getIngressRateLimitInBytesPerSecond(@NonNull Context context) { + return Settings.Global.getLong(context.getContentResolver(), + INGRESS_RATE_LIMIT_BYTES_PER_SECOND, -1); + } + + /** + * Set the global network bandwidth rate limit. + * + * The limit is only applicable to networks that provide internet connectivity. + * + * @param context The {@link Context} to set the setting. + * @param rateLimitInBytesPerSec The rate limit in number of bytes per second or -1 to disable. + */ + public static void setIngressRateLimitInBytesPerSecond(@NonNull Context context, + @IntRange(from = -1, to = Integer.MAX_VALUE) long rateLimitInBytesPerSec) { + if (rateLimitInBytesPerSec < -1) { + throw new IllegalArgumentException( + "Rate limit must be within the range [-1, Integer.MAX_VALUE]"); + } + Settings.Global.putLong(context.getContentResolver(), + INGRESS_RATE_LIMIT_BYTES_PER_SECOND, + rateLimitInBytesPerSec); + } } diff --git a/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt b/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt index ebaa787cc6..8d8958dd93 100644 --- a/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt +++ b/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt @@ -39,6 +39,7 @@ import android.net.ConnectivitySettingsManager.getConnectivityKeepPendingIntentD import android.net.ConnectivitySettingsManager.getDnsResolverSampleRanges import android.net.ConnectivitySettingsManager.getDnsResolverSampleValidityDuration import android.net.ConnectivitySettingsManager.getDnsResolverSuccessThresholdPercent +import android.net.ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond import android.net.ConnectivitySettingsManager.getMobileDataActivityTimeout import android.net.ConnectivitySettingsManager.getMobileDataAlwaysOn import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationMaximumDailyCount @@ -51,6 +52,7 @@ import android.net.ConnectivitySettingsManager.setConnectivityKeepPendingIntentD import android.net.ConnectivitySettingsManager.setDnsResolverSampleRanges import android.net.ConnectivitySettingsManager.setDnsResolverSampleValidityDuration import android.net.ConnectivitySettingsManager.setDnsResolverSuccessThresholdPercent +import android.net.ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond import android.net.ConnectivitySettingsManager.setMobileDataActivityTimeout import android.net.ConnectivitySettingsManager.setMobileDataAlwaysOn import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationMaximumDailyCount @@ -292,4 +294,19 @@ class ConnectivitySettingsManagerTest { setter = { setWifiAlwaysRequested(context, it) }, testIntValues = intArrayOf(0)) } + + @Test + fun testInternetNetworkRateLimitInBytesPerSecond() { + val defaultRate = getIngressRateLimitInBytesPerSecond(context) + val testRate = 1000L + setIngressRateLimitInBytesPerSecond(context, testRate) + assertEquals(testRate, getIngressRateLimitInBytesPerSecond(context)) + + setIngressRateLimitInBytesPerSecond(context, defaultRate) + assertEquals(defaultRate, getIngressRateLimitInBytesPerSecond(context)) + + assertFailsWith("Expected failure, but setting accepted") { + setIngressRateLimitInBytesPerSecond(context, -10) + } + } } \ No newline at end of file