diff --git a/bpf_progs/netd.h b/bpf_progs/netd.h index d1fc58d627..64ed633277 100644 --- a/bpf_progs/netd.h +++ b/bpf_progs/netd.h @@ -192,6 +192,7 @@ enum UidOwnerMatchType { OEM_DENY_1_MATCH = (1 << 9), OEM_DENY_2_MATCH = (1 << 10), OEM_DENY_3_MATCH = (1 << 11), + BACKGROUND_MATCH = (1 << 12) }; // LINT.ThenChange(../framework/src/android/net/BpfNetMapsConstants.java) @@ -244,7 +245,8 @@ STRUCT_SIZE(IngressDiscardValue, 2 * 4); // 8 // DROP_IF_SET is set of rules that DROP if rule is globally enabled, and per-uid bit is set #define DROP_IF_SET (STANDBY_MATCH | OEM_DENY_1_MATCH | OEM_DENY_2_MATCH | OEM_DENY_3_MATCH) // DROP_IF_UNSET is set of rules that should DROP if globally enabled, and per-uid bit is NOT set -#define DROP_IF_UNSET (DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH | LOW_POWER_STANDBY_MATCH) +#define DROP_IF_UNSET (DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH \ + | LOW_POWER_STANDBY_MATCH | BACKGROUND_MATCH) // Warning: funky bit-wise arithmetic: in parallel, for all DROP_IF_SET/UNSET rules // check whether the rules are globally enabled, and if so whether the rules are diff --git a/common/flags.aconfig b/common/flags.aconfig index 0c46b4882c..b85c2fefe5 100644 --- a/common/flags.aconfig +++ b/common/flags.aconfig @@ -34,3 +34,10 @@ flag { description: "This flag controls whether isUidNetworkingBlocked is supported" bug: "297836825" } + +flag { + name: "basic_background_restrictions_enabled" + namespace: "android_core_networking" + description: "Block network access for apps in a low importance background state" + bug: "304347838" +} diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index 4d550678f1..bfb498114a 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -45,6 +45,7 @@ package android.net { field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000 field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000 field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000 + field @FlaggedApi("com.android.net.flags.basic_background_restrictions_enabled") public static final int BLOCKED_REASON_APP_BACKGROUND = 64; // 0x40 field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4 field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1 field public static final int BLOCKED_REASON_DOZE = 2; // 0x2 @@ -52,6 +53,7 @@ package android.net { field public static final int BLOCKED_REASON_LOW_POWER_STANDBY = 32; // 0x20 field public static final int BLOCKED_REASON_NONE = 0; // 0x0 field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8 + field @FlaggedApi("com.android.net.flags.basic_background_restrictions_enabled") public static final int FIREWALL_CHAIN_BACKGROUND = 6; // 0x6 field public static final int FIREWALL_CHAIN_DOZABLE = 1; // 0x1 field public static final int FIREWALL_CHAIN_LOW_POWER_STANDBY = 5; // 0x5 field public static final int FIREWALL_CHAIN_OEM_DENY_1 = 7; // 0x7 diff --git a/framework/src/android/net/BpfNetMapsConstants.java b/framework/src/android/net/BpfNetMapsConstants.java index c7845979e6..5d0fe73ca4 100644 --- a/framework/src/android/net/BpfNetMapsConstants.java +++ b/framework/src/android/net/BpfNetMapsConstants.java @@ -16,6 +16,7 @@ package android.net; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -77,6 +78,7 @@ public class BpfNetMapsConstants { public static final long OEM_DENY_1_MATCH = (1 << 9); public static final long OEM_DENY_2_MATCH = (1 << 10); public static final long OEM_DENY_3_MATCH = (1 << 11); + public static final long BACKGROUND_MATCH = (1 << 12); public static final List> MATCH_LIST = Arrays.asList( Pair.create(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"), @@ -90,7 +92,8 @@ public class BpfNetMapsConstants { Pair.create(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"), Pair.create(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"), Pair.create(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"), - Pair.create(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH") + Pair.create(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH"), + Pair.create(BACKGROUND_MATCH, "BACKGROUND_MATCH") ); /** @@ -102,7 +105,8 @@ public class BpfNetMapsConstants { FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, - FIREWALL_CHAIN_LOW_POWER_STANDBY + FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND ); /** diff --git a/framework/src/android/net/BpfNetMapsUtils.java b/framework/src/android/net/BpfNetMapsUtils.java index e9c9137e37..11d610cbfe 100644 --- a/framework/src/android/net/BpfNetMapsUtils.java +++ b/framework/src/android/net/BpfNetMapsUtils.java @@ -17,6 +17,7 @@ package android.net; import static android.net.BpfNetMapsConstants.ALLOW_CHAINS; +import static android.net.BpfNetMapsConstants.BACKGROUND_MATCH; import static android.net.BpfNetMapsConstants.DENY_CHAINS; import static android.net.BpfNetMapsConstants.DOZABLE_MATCH; import static android.net.BpfNetMapsConstants.LOW_POWER_STANDBY_MATCH; @@ -28,6 +29,7 @@ import static android.net.BpfNetMapsConstants.OEM_DENY_3_MATCH; import static android.net.BpfNetMapsConstants.POWERSAVE_MATCH; import static android.net.BpfNetMapsConstants.RESTRICTED_MATCH; import static android.net.BpfNetMapsConstants.STANDBY_MATCH; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -70,6 +72,8 @@ public class BpfNetMapsUtils { return POWERSAVE_MATCH; case FIREWALL_CHAIN_RESTRICTED: return RESTRICTED_MATCH; + case FIREWALL_CHAIN_BACKGROUND: + return BACKGROUND_MATCH; case FIREWALL_CHAIN_LOW_POWER_STANDBY: return LOW_POWER_STANDBY_MATCH; case FIREWALL_CHAIN_OEM_DENY_1: diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 586e4b0d6b..57ecf4968a 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -135,6 +135,8 @@ public class ConnectivityManager { "com.android.net.flags.set_data_saver_via_cm"; static final String SUPPORT_IS_UID_NETWORKING_BLOCKED = "com.android.net.flags.support_is_uid_networking_blocked"; + static final String BASIC_BACKGROUND_RESTRICTIONS_ENABLED = + "com.android.net.flags.basic_background_restrictions_enabled"; } /** @@ -907,6 +909,16 @@ public class ConnectivityManager { @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int BLOCKED_REASON_LOW_POWER_STANDBY = 1 << 5; + /** + * Flag to indicate that an app is subject to default background restrictions that would + * result in its network access being blocked. + * + * @hide + */ + @FlaggedApi(Flags.BASIC_BACKGROUND_RESTRICTIONS_ENABLED) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int BLOCKED_REASON_APP_BACKGROUND = 1 << 6; + /** * Flag to indicate that an app is subject to Data saver restrictions that would * result in its metered network access being blocked. @@ -946,6 +958,7 @@ public class ConnectivityManager { BLOCKED_REASON_RESTRICTED_MODE, BLOCKED_REASON_LOCKDOWN_VPN, BLOCKED_REASON_LOW_POWER_STANDBY, + BLOCKED_REASON_APP_BACKGROUND, BLOCKED_METERED_REASON_DATA_SAVER, BLOCKED_METERED_REASON_USER_RESTRICTED, BLOCKED_METERED_REASON_ADMIN_DISABLED, @@ -1003,6 +1016,16 @@ public class ConnectivityManager { @SystemApi(client = MODULE_LIBRARIES) public static final int FIREWALL_CHAIN_LOW_POWER_STANDBY = 5; + /** + * Firewall chain used for always-on default background restrictions. + * Allowlist of apps that have access because either they are in the foreground or they are + * exempted for specific situations while in the background. + * @hide + */ + @FlaggedApi(Flags.BASIC_BACKGROUND_RESTRICTIONS_ENABLED) + @SystemApi(client = MODULE_LIBRARIES) + public static final int FIREWALL_CHAIN_BACKGROUND = 6; + /** * Firewall chain used for OEM-specific application restrictions. * @@ -1062,6 +1085,7 @@ public class ConnectivityManager { FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_CHAIN_OEM_DENY_3 diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index d8417c1541..47e0bd9a7f 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -12884,6 +12884,7 @@ public class ConnectivityService extends IConnectivityManager.Stub case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: + case ConnectivityManager.FIREWALL_CHAIN_BACKGROUND: defaultRule = FIREWALL_RULE_DENY; break; default: diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 62614c1231..0a143c538a 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -38,6 +38,7 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.EXTRA_NETWORK; import static android.net.ConnectivityManager.EXTRA_NETWORK_REQUEST; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -3538,6 +3539,12 @@ public class ConnectivityManagerTest { doTestFirewallBlocking(FIREWALL_CHAIN_DOZABLE, ALLOWLIST); } + @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @ConnectivityModuleTest + @AppModeFull(reason = "Socket cannot bind in instant app mode") + public void testFirewallBlockingBackground() { + doTestFirewallBlocking(FIREWALL_CHAIN_BACKGROUND, ALLOWLIST); + } + @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest @AppModeFull(reason = "Socket cannot bind in instant app mode") public void testFirewallBlockingPowersave() { diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index aae37e5630..bafd450ff3 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -59,6 +59,7 @@ import static android.net.ConnectivityManager.EXTRA_IS_ACTIVE; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.EXTRA_REALTIME_NS; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -10475,6 +10476,7 @@ public class ConnectivityServiceTest { doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY); doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY); doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY); + doTestSetUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, FIREWALL_RULE_DENY); doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW); doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW); doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW); @@ -10488,6 +10490,7 @@ public class ConnectivityServiceTest { FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_CHAIN_OEM_DENY_3); @@ -10537,6 +10540,7 @@ public class ConnectivityServiceTest { doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_POWERSAVE, allowlist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_RESTRICTED, allowlist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_LOW_POWER_STANDBY, allowlist); + doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_BACKGROUND, allowlist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_STANDBY, denylist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_1, denylist); @@ -10558,6 +10562,7 @@ public class ConnectivityServiceTest { doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE); doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED); doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY); + doTestReplaceFirewallChain(FIREWALL_CHAIN_BACKGROUND); doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1); doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2); doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3);