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

Commit 331beba8 authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Restricting network for low-priority proc-states

Outside of power saving modes like battery saver and doze, network
is freely available to any app that is in memory and can run code on
the processor. However, networking is a power expensive resource and
needs to be used judiciously.

The platform policy will now restrict any apps that are in cached or
nearby process-states that are not important to the user. Any user
critical networking task must be done while being in active and valid
lifecycle states only.
The system will allow a grace period of few seconds to reduce any churn
from quick proc-state transitions but apps should ideally not rely on
this implementation detail.

Apps that are in any of the power allowlists will be exempt from this
restriction.

Refactored some code to use more inclusive language.

Test: atest FrameworksServicesTests:com.android.server.net
Test: atest CtsHostsideNetworkTests

BYPASS_INCLUSIVE_LANGUAGE_REASON=Existing code

Bug: 304347838
Change-Id: I02d82dc88c46ee7eec7e428fd46d0a538481494d
parent b4d3b80e
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.net;

import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
import static android.app.ActivityManager.procStateToString;
import static android.content.pm.PackageManager.GET_SIGNATURES;
@@ -170,6 +171,8 @@ public class NetworkPolicyManager {
    public static final String FIREWALL_CHAIN_NAME_RESTRICTED = "restricted";
    /** @hide */
    public static final String FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY = "low_power_standby";
    /** @hide */
    public static final String FIREWALL_CHAIN_NAME_BACKGROUND = "background";

    private static final boolean ALLOW_PLATFORM_APP_POLICY = true;

@@ -180,6 +183,9 @@ public class NetworkPolicyManager {
    /** @hide */
    public static final int TOP_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_BOUND_TOP;

    /** @hide */
    public static final int BACKGROUND_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_TOP_SLEEPING;

    /**
     * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
     * applies to.
@@ -264,6 +270,16 @@ public class NetworkPolicyManager {
     * @hide
     */
    public static final int ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST = 1 << 6;

    /**
     * Flag to indicate that the app is exempt from always-on background network restrictions.
     * Note that this is explicitly different to the flag NOT_FOREGROUND which is used to grant
     * shared exception to apps from power restrictions like doze, battery saver and app-standby.
     *
     * @hide
     */
    public static final int ALLOWED_REASON_NOT_IN_BACKGROUND = 1 << 7;

    /**
     * Flag to indicate that app is exempt from certain metered network restrictions because user
     * explicitly exempted it.
@@ -821,6 +837,21 @@ public class NetworkPolicyManager {
        return uidState.procState <= TOP_THRESHOLD_STATE;
    }

    /**
     * This is currently only used as an implementation detail for
     * {@link com.android.server.net.NetworkPolicyManagerService}.
     * Only put here to be together with other isProcStateAllowed* methods.
     *
     * @hide
     */
    public static boolean isProcStateAllowedNetworkWhileBackground(@Nullable UidState uidState) {
        if (uidState == null) {
            return false;
        }
        return uidState.procState < BACKGROUND_THRESHOLD_STATE
                || (uidState.capability & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;
    }

    /**
     * Returns true if {@param procState} is considered foreground and as such will be allowed
     * to access network when the device is in data saver mode. Otherwise, false.
+1 −0
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ java_library_static {
        "com.android.server.utils_aconfig-java",
        "service-jobscheduler-deviceidle.flags-aconfig-java",
        "policy_flags_lib",
        "net_flags_lib",
    ],
    javac_shard_size: 50,
    javacflags: [
+10 −0
Original line number Diff line number Diff line
aconfig_declarations {
    name: "net_flags",
    package: "com.android.server.net",
    srcs: ["*.aconfig"],
}

java_aconfig_library {
    name: "net_flags_lib",
    aconfig_declarations: "net_flags",
}
+27 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.net;

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_POWERSAVE;
@@ -27,6 +28,7 @@ import static android.net.INetd.FIREWALL_CHAIN_NONE;
import static android.net.INetd.FIREWALL_DENYLIST;
import static android.net.INetd.FIREWALL_RULE_ALLOW;
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_POWERSAVE;
@@ -187,6 +189,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
     */
    @GuardedBy("mRulesLock")
    private final SparseIntArray mUidFirewallLowPowerStandbyRules = new SparseIntArray();

    /**
     * Contains the per-UID firewall rules that are used when Background chain is enabled.
     */
    @GuardedBy("mRulesLock")
    private final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray();

    /** Set of states for the child firewall chains. True if the chain is active. */
    @GuardedBy("mRulesLock")
    final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
@@ -449,13 +458,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
            syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
            syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted ");
            syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby ");
            syncFirewallChainLocked(FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_NAME_BACKGROUND);

            final int[] chains = {
                    FIREWALL_CHAIN_STANDBY,
                    FIREWALL_CHAIN_DOZABLE,
                    FIREWALL_CHAIN_POWERSAVE,
                    FIREWALL_CHAIN_RESTRICTED,
                    FIREWALL_CHAIN_LOW_POWER_STANDBY
                    FIREWALL_CHAIN_LOW_POWER_STANDBY,
                    FIREWALL_CHAIN_BACKGROUND,
            };

            for (int chain : chains) {
@@ -1206,6 +1217,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                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);
        }
@@ -1223,6 +1236,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                return FIREWALL_ALLOWLIST;
            case FIREWALL_CHAIN_LOW_POWER_STANDBY:
                return FIREWALL_ALLOWLIST;
            case FIREWALL_CHAIN_BACKGROUND:
                return FIREWALL_ALLOWLIST;
            default:
                return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST;
        }
@@ -1343,6 +1358,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                return mUidFirewallRestrictedRules;
            case FIREWALL_CHAIN_LOW_POWER_STANDBY:
                return mUidFirewallLowPowerStandbyRules;
            case FIREWALL_CHAIN_BACKGROUND:
                return mUidFirewallBackgroundRules;
            case FIREWALL_CHAIN_NONE:
                return mUidFirewallRules;
            default:
@@ -1395,6 +1412,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
            pw.println(getFirewallChainState(FIREWALL_CHAIN_LOW_POWER_STANDBY));
            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY,
                    mUidFirewallLowPowerStandbyRules);

            pw.print("UID firewall background chain enabled: ");
            pw.println(getFirewallChainState(FIREWALL_CHAIN_BACKGROUND));
            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_BACKGROUND, mUidFirewallBackgroundRules);
        }

        pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
@@ -1494,6 +1515,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of low power standby");
                return true;
            }
            if (getFirewallChainState(FIREWALL_CHAIN_BACKGROUND)
                    && mUidFirewallBackgroundRules.get(uid) != FIREWALL_RULE_ALLOW) {
                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because it is in background");
                return true;
            }
            if (mUidRejectOnMetered.get(uid)) {
                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
                        + " in the background");
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.net;

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_POWERSAVE;
@@ -24,6 +25,7 @@ import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
import static android.net.INetd.FIREWALL_RULE_ALLOW;
import static android.net.INetd.FIREWALL_RULE_DENY;
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_POWERSAVE;
@@ -389,6 +391,8 @@ public class NetworkPolicyLogger {
                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:
                return String.valueOf(chain);
        }
Loading