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

Commit 4fe212f6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Use metered firewalls for metered uid policy" into main am: a19281e0

parents a31c03e7 a19281e0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -173,6 +173,12 @@ public class NetworkPolicyManager {
    public static final String FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY = "low_power_standby";
    /** @hide */
    public static final String FIREWALL_CHAIN_NAME_BACKGROUND = "background";
    /** @hide */
    public static final String FIREWALL_CHAIN_NAME_METERED_ALLOW = "metered_allow";
    /** @hide */
    public static final String FIREWALL_CHAIN_NAME_METERED_DENY_USER = "metered_deny_user";
    /** @hide */
    public static final String FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN = "metered_deny_admin";

    private static final boolean ALLOW_PLATFORM_APP_POLICY = true;

+169 −59
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
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_METERED_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
@@ -31,6 +34,9 @@ import static android.net.INetd.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_ALLOW;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_USER;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
@@ -143,6 +149,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
    private final Object mQuotaLock = new Object();
    private final Object mRulesLock = new Object();

    private final boolean mUseMeteredFirewallChains;

    /** Set of interfaces with active quotas. */
    @GuardedBy("mQuotaLock")
    private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
@@ -150,9 +158,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
    @GuardedBy("mQuotaLock")
    private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
    /** Set of UIDs denied on metered networks. */
    // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains.
    @GuardedBy("mRulesLock")
    private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
    /** Set of UIDs allowed on metered networks. */
    // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains.
    @GuardedBy("mRulesLock")
    private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
    /** Set of UIDs with cleartext penalties. */
@@ -196,10 +206,32 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
    @GuardedBy("mRulesLock")
    private final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray();

    /**
     * Contains the per-UID firewall rules that are used to allowlist the app from metered-network
     * restrictions when data saver is enabled.
     */
    @GuardedBy("mRulesLock")
    private final SparseIntArray mUidMeteredFirewallAllowRules = new SparseIntArray();

    /**
     * Contains the per-UID firewall rules that are used to deny app access to metered networks
     * due to user action.
     */
    @GuardedBy("mRulesLock")
    private final SparseIntArray mUidMeteredFirewallDenyUserRules = new SparseIntArray();

    /**
     * Contains the per-UID firewall rules that are used to deny app access to metered networks
     * due to admin action.
     */
    @GuardedBy("mRulesLock")
    private final SparseIntArray mUidMeteredFirewallDenyAdminRules = new SparseIntArray();

    /** Set of states for the child firewall chains. True if the chain is active. */
    @GuardedBy("mRulesLock")
    final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();

    // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains.
    @GuardedBy("mQuotaLock")
    private volatile boolean mDataSaverMode;

@@ -217,6 +249,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
        mContext = context;
        mDeps = deps;

        mUseMeteredFirewallChains = Flags.useMeteredFirewallChains();

        if (mUseMeteredFirewallChains) {
            // These firewalls are always on and currently ConnectivityService does not allow
            // changing their enabled state.
            mFirewallChainStates.put(FIREWALL_CHAIN_METERED_DENY_USER, true);
            mFirewallChainStates.put(FIREWALL_CHAIN_METERED_DENY_ADMIN, true);
        }

        mDaemonHandler = new Handler(FgThread.get().getLooper());

        mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
@@ -410,19 +451,24 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                }
            }

            if (!mUseMeteredFirewallChains) {
                SparseBooleanArray uidRejectOnQuota = null;
                SparseBooleanArray uidAcceptOnQuota = null;
                synchronized (mRulesLock) {
                    size = mUidRejectOnMetered.size();
                    if (size > 0) {
                    if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules");
                        if (DBG) {
                            Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules");
                        }
                        uidRejectOnQuota = mUidRejectOnMetered;
                        mUidRejectOnMetered = new SparseBooleanArray();
                    }

                    size = mUidAllowOnMetered.size();
                    if (size > 0) {
                    if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules");
                        if (DBG) {
                            Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules");
                        }
                        uidAcceptOnQuota = mUidAllowOnMetered;
                        mUidAllowOnMetered = new SparseBooleanArray();
                    }
@@ -439,6 +485,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                                uidAcceptOnQuota.valueAt(i));
                    }
                }
            }

            size = mUidCleartextPolicy.size();
            if (size > 0) {
@@ -459,8 +506,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
            syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted ");
            syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby ");
            syncFirewallChainLocked(FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_NAME_BACKGROUND);
            if (mUseMeteredFirewallChains) {
                syncFirewallChainLocked(FIREWALL_CHAIN_METERED_ALLOW,
                        FIREWALL_CHAIN_NAME_METERED_ALLOW);
                syncFirewallChainLocked(FIREWALL_CHAIN_METERED_DENY_USER,
                        FIREWALL_CHAIN_NAME_METERED_DENY_USER);
                syncFirewallChainLocked(FIREWALL_CHAIN_METERED_DENY_ADMIN,
                        FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN);
            }

            final int[] chains = {
            final int[] chainsToEnable = {
                    FIREWALL_CHAIN_STANDBY,
                    FIREWALL_CHAIN_DOZABLE,
                    FIREWALL_CHAIN_POWERSAVE,
@@ -469,14 +524,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                    FIREWALL_CHAIN_BACKGROUND,
            };

            for (int chain : chains) {
            for (int chain : chainsToEnable) {
                if (getFirewallChainState(chain)) {
                    setFirewallChainEnabled(chain, true);
                }
            }
        }


        try {
            getBatteryStats().noteNetworkStatsEnabled();
        } catch (RemoteException e) {
@@ -1077,6 +1131,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                    mContext.getSystemService(ConnectivityManager.class)
                            .setDataSaverEnabled(enable);
                    mDataSaverMode = enable;
                    if (mUseMeteredFirewallChains) {
                        // Copy mDataSaverMode state to FIREWALL_CHAIN_METERED_ALLOW
                        // until ConnectivityService allows manipulation of the data saver mode via
                        // FIREWALL_CHAIN_METERED_ALLOW.
                        synchronized (mRulesLock) {
                            mFirewallChainStates.put(FIREWALL_CHAIN_METERED_ALLOW, enable);
                        }
                    }
                    return true;
                } else {
                    final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
@@ -1191,9 +1253,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                setFirewallChainState(chain, enable);
            }

            final String chainName = getFirewallChainName(chain);
            if (chain == FIREWALL_CHAIN_NONE) {
                throw new IllegalArgumentException("Bad child chain: " + chainName);
            if (!isValidFirewallChainForSetEnabled(chain)) {
                throw new IllegalArgumentException("Invalid chain for setFirewallChainEnabled: "
                        + NetworkPolicyLogger.getFirewallChainName(chain));
            }

            final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
@@ -1205,38 +1267,29 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
        }
    }

    private String getFirewallChainName(int chain) {
        switch (chain) {
            case FIREWALL_CHAIN_STANDBY:
                return FIREWALL_CHAIN_NAME_STANDBY;
            case FIREWALL_CHAIN_DOZABLE:
                return FIREWALL_CHAIN_NAME_DOZABLE;
            case FIREWALL_CHAIN_POWERSAVE:
                return FIREWALL_CHAIN_NAME_POWERSAVE;
            case FIREWALL_CHAIN_RESTRICTED:
                return FIREWALL_CHAIN_NAME_RESTRICTED;
            case FIREWALL_CHAIN_LOW_POWER_STANDBY:
                return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
            case FIREWALL_CHAIN_BACKGROUND:
                return FIREWALL_CHAIN_NAME_BACKGROUND;
            default:
                throw new IllegalArgumentException("Bad child chain: " + chain);
        }
    private boolean isValidFirewallChainForSetEnabled(int chain) {
        return switch (chain) {
            case FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE,
                    FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY,
                    FIREWALL_CHAIN_BACKGROUND -> true;
            // METERED_* firewall chains are not yet supported by
            // ConnectivityService#setFirewallChainEnabled.
            default -> false;
        };
    }

    private int getFirewallType(int chain) {
        switch (chain) {
            case FIREWALL_CHAIN_STANDBY:
            case FIREWALL_CHAIN_METERED_DENY_ADMIN:
            case FIREWALL_CHAIN_METERED_DENY_USER:
                return FIREWALL_DENYLIST;
            case FIREWALL_CHAIN_DOZABLE:
                return FIREWALL_ALLOWLIST;
            case FIREWALL_CHAIN_POWERSAVE:
                return FIREWALL_ALLOWLIST;
            case FIREWALL_CHAIN_RESTRICTED:
                return FIREWALL_ALLOWLIST;
            case FIREWALL_CHAIN_LOW_POWER_STANDBY:
                return FIREWALL_ALLOWLIST;
            case FIREWALL_CHAIN_BACKGROUND:
            case FIREWALL_CHAIN_METERED_ALLOW:
                return FIREWALL_ALLOWLIST;
            default:
                return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST;
@@ -1360,6 +1413,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                return mUidFirewallLowPowerStandbyRules;
            case FIREWALL_CHAIN_BACKGROUND:
                return mUidFirewallBackgroundRules;
            case FIREWALL_CHAIN_METERED_ALLOW:
                return mUidMeteredFirewallAllowRules;
            case FIREWALL_CHAIN_METERED_DENY_USER:
                return mUidMeteredFirewallDenyUserRules;
            case FIREWALL_CHAIN_METERED_DENY_ADMIN:
                return mUidMeteredFirewallDenyAdminRules;
            case FIREWALL_CHAIN_NONE:
                return mUidFirewallRules;
            default:
@@ -1378,6 +1437,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;

        pw.println("Flags:");
        pw.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": " + mUseMeteredFirewallChains);
        pw.println();

        synchronized (mQuotaLock) {
            pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
            pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
@@ -1416,6 +1479,27 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
            pw.print("UID firewall background chain enabled: ");
            pw.println(getFirewallChainState(FIREWALL_CHAIN_BACKGROUND));
            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_BACKGROUND, mUidFirewallBackgroundRules);

            pw.print("UID firewall metered allow chain enabled (Data saver mode): ");
            // getFirewallChainState should maintain a duplicated state from mDataSaverMode when
            // mUseMeteredFirewallChains is enabled.
            pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_ALLOW));
            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_ALLOW,
                    mUidMeteredFirewallAllowRules);

            pw.print("UID firewall metered deny_user chain enabled (always-on): ");
            // This always-on state should be reflected by getFirewallChainState when
            // mUseMeteredFirewallChains is enabled.
            pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_USER));
            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_DENY_USER,
                    mUidMeteredFirewallDenyUserRules);

            pw.print("UID firewall metered deny_admin chain enabled (always-on): ");
            // This always-on state should be reflected by getFirewallChainState when
            // mUseMeteredFirewallChains is enabled.
            pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_ADMIN));
            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN,
                    mUidMeteredFirewallDenyAdminRules);
        }

        pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
@@ -1520,15 +1604,41 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because it is in background");
                return true;
            }
            if (mUseMeteredFirewallChains) {
                if (getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_USER)
                        && mUidMeteredFirewallDenyUserRules.get(uid) == FIREWALL_RULE_DENY) {
                    if (DBG) {
                        Slog.d(TAG, "Uid " + uid + " restricted because of user-restricted metered"
                                + " data in the background");
                    }
                    return true;
                }
                if (getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_ADMIN)
                        && mUidMeteredFirewallDenyAdminRules.get(uid) == FIREWALL_RULE_DENY) {
                    if (DBG) {
                        Slog.d(TAG, "Uid " + uid + " restricted because of admin-restricted metered"
                                + " data in the background");
                    }
                    return true;
                }
                if (getFirewallChainState(FIREWALL_CHAIN_METERED_ALLOW)
                        && mUidMeteredFirewallAllowRules.get(uid) != FIREWALL_RULE_ALLOW) {
                    if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
                    return true;
                }
            } else {
                if (mUidRejectOnMetered.get(uid)) {
                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
                        + " in the background");
                    if (DBG) {
                        Slog.d(TAG, "Uid " + uid
                                + " restricted because of no metered data in the background");
                    }
                    return true;
                }
                if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
                    if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
                    return true;
                }
            }
            return false;
        }
    }
+13 −1
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
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_METERED_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
@@ -28,6 +31,9 @@ import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_ALLOW;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_USER;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
@@ -379,7 +385,7 @@ public class NetworkPolicyLogger {
        return "Interfaces of netId=" + netId + " changed to " + newIfaces;
    }

    private static String getFirewallChainName(int chain) {
    static String getFirewallChainName(int chain) {
        switch (chain) {
            case FIREWALL_CHAIN_DOZABLE:
                return FIREWALL_CHAIN_NAME_DOZABLE;
@@ -393,6 +399,12 @@ public class NetworkPolicyLogger {
                return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
            case FIREWALL_CHAIN_BACKGROUND:
                return FIREWALL_CHAIN_NAME_BACKGROUND;
            case FIREWALL_CHAIN_METERED_ALLOW:
                return FIREWALL_CHAIN_NAME_METERED_ALLOW;
            case FIREWALL_CHAIN_METERED_DENY_USER:
                return FIREWALL_CHAIN_NAME_METERED_DENY_USER;
            case FIREWALL_CHAIN_METERED_DENY_ADMIN:
                return FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN;
            default:
                return String.valueOf(chain);
        }
+67 −22
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
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_METERED_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
@@ -514,6 +517,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
     */
    private boolean mBackgroundNetworkRestricted;

    /**
     * Whether or not metered firewall chains should be used for uid policy controlling access to
     * metered networks.
     */
    private boolean mUseMeteredFirewallChains;

    // See main javadoc for instructions on how to use these locks.
    final Object mUidRulesFirstLock = new Object();
    final Object mNetworkPoliciesSecondLock = new Object();
@@ -997,6 +1006,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            mAppStandby = LocalServices.getService(AppStandbyInternal.class);
            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);

            mUseMeteredFirewallChains = Flags.useMeteredFirewallChains();

            synchronized (mUidRulesFirstLock) {
                synchronized (mNetworkPoliciesSecondLock) {
                    updatePowerSaveAllowlistUL();
@@ -4030,8 +4041,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {

                fout.println();
                fout.println("Flags:");
                fout.println("Network blocked for TOP_SLEEPING and above: "
                fout.println(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE + ": "
                        + mBackgroundNetworkRestricted);
                fout.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": "
                        + mUseMeteredFirewallChains);

                fout.println();
                fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode);
@@ -5367,6 +5380,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            postUidRulesChangedMsg(uid, uidRules);
        }

        if (mUseMeteredFirewallChains) {
            if ((newEffectiveBlockedReasons & BLOCKED_METERED_REASON_ADMIN_DISABLED)
                    != BLOCKED_REASON_NONE) {
                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, FIREWALL_RULE_DENY);
            } else {
                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, FIREWALL_RULE_DEFAULT);
            }
            if ((newEffectiveBlockedReasons & BLOCKED_METERED_REASON_USER_RESTRICTED)
                    != BLOCKED_REASON_NONE) {
                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DENY);
            } else {
                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DEFAULT);
            }
            if ((newAllowedReasons & (ALLOWED_METERED_REASON_FOREGROUND
                    | ALLOWED_METERED_REASON_USER_EXEMPTED)) != ALLOWED_REASON_NONE) {
                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_ALLOW);
            } else {
                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_DEFAULT);
            }
        } else {
            // Note that the conditionals below are for avoiding unnecessary calls to netd.
            // TODO: Measure the performance for doing a no-op call to netd so that we can
            // remove the conditionals to simplify the logic below. We can also further reduce
@@ -5386,6 +5419,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                        (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE);
            }
        }
    }

    /**
     * Updates the power-related part of the {@link #mUidBlockedState} for a given map, and
@@ -6143,6 +6177,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            } else if (chain == FIREWALL_CHAIN_BACKGROUND) {
                mUidFirewallBackgroundRules.put(uid, rule);
            }
            // Note that we do not need keep a separate cache of uid rules for chains that we do
            // not call #setUidFirewallRulesUL for.

            try {
                mNetworkManager.setFirewallUidRule(chain, uid, rule);
@@ -6200,10 +6236,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                    FIREWALL_RULE_DEFAULT);
            mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, uid,
                    FIREWALL_RULE_DEFAULT);
            if (mUseMeteredFirewallChains) {
                mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid,
                        FIREWALL_RULE_DEFAULT);
                mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, uid,
                        FIREWALL_RULE_DEFAULT);
                mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, uid,
                        FIREWALL_RULE_DEFAULT);
            } else {
                mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
                mLogger.meteredAllowlistChanged(uid, false);
                mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
                mLogger.meteredDenylistChanged(uid, false);
            }
        } catch (IllegalStateException e) {
            Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
        } catch (RemoteException e) {
+10 −0
Original line number Diff line number Diff line
@@ -7,3 +7,13 @@ flag {
    description: "Block network access for apps in a low importance background state"
    bug: "304347838"
}

flag {
    name: "use_metered_firewall_chains"
    namespace: "backstage_power"
    description: "Use metered firewall chains to control access to metered networks"
    bug: "336693007"
    metadata {
      purpose: PURPOSE_BUGFIX
    }
}
Loading