diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index c128852644..de51eb474d 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -12,6 +12,7 @@ package android.net { method @NonNull public static android.util.Range getIpSecNetIdRange(); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean); diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index dcd33e5540..79a3757e81 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -5682,4 +5682,28 @@ public class ConnectivityManager { throw e.rethrowFromSystemServer(); } } + + /** + * Replaces the contents of the specified UID-based firewall chain. + * + * @param chain target chain to replace. + * @param uids The list of UIDs to be placed into chain. + * @throws IllegalStateException if replace firewall chain failed. + * @throws IllegalArgumentException if {@code chain} is not a valid chain. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK + }) + public void replaceFirewallChain(@FirewallChain final int chain, @NonNull final int[] uids) { + Objects.requireNonNull(uids); + try { + mService.replaceFirewallChain(chain, uids); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl index f5968a6206..0e224afc0d 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -238,4 +238,6 @@ interface IConnectivityManager void updateFirewallRule(int chain, int uid, boolean allow); void setFirewallChainEnabled(int chain, boolean enable); + + void replaceFirewallChain(int chain, in int[] uids); } diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 292d1c1969..1fe35ad0dc 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -10634,4 +10634,30 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + @Override + public void replaceFirewallChain(final int chain, final int[] uids) { + enforceNetworkStackOrSettingsPermission(); + + try { + switch (chain) { + case ConnectivityManager.FIREWALL_CHAIN_DOZABLE: + mNetd.firewallReplaceUidChain("fw_dozable", true /* isAllowList */, uids); + break; + case ConnectivityManager.FIREWALL_CHAIN_STANDBY: + mNetd.firewallReplaceUidChain("fw_standby", false /* isAllowList */, uids); + break; + case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: + mNetd.firewallReplaceUidChain("fw_powersave", true /* isAllowList */, uids); + break; + case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: + mNetd.firewallReplaceUidChain("fw_restricted", true /* isAllowList */, uids); + break; + default: + throw new IllegalArgumentException("replaceFirewallChain with invalid chain: " + + chain); + } + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); + } + } }