Merge "Add Low Power Standby support to NetworkPolicyManagerService"
This commit is contained in:
@@ -176,6 +176,9 @@ public class NetworkPolicyManager {
|
||||
public static final int FOREGROUND_THRESHOLD_STATE =
|
||||
ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
|
||||
|
||||
/** @hide */
|
||||
public static final int TOP_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_BOUND_TOP;
|
||||
|
||||
/**
|
||||
* {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
|
||||
* applies to.
|
||||
@@ -246,6 +249,20 @@ public class NetworkPolicyManager {
|
||||
* @hide
|
||||
*/
|
||||
public static final int ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS = 1 << 4;
|
||||
/**
|
||||
* Flag to indicate that app is exempt from certain network restrictions because of it being
|
||||
* in the bound top or top procstate.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ALLOWED_REASON_TOP = 1 << 5;
|
||||
/**
|
||||
* Flag to indicate that app is exempt from low power standby restrictions because of it being
|
||||
* allowlisted.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST = 1 << 6;
|
||||
/**
|
||||
* Flag to indicate that app is exempt from certain metered network restrictions because user
|
||||
* explicitly exempted it.
|
||||
@@ -770,6 +787,14 @@ public class NetworkPolicyManager {
|
||||
|| (capability & ActivityManager.PROCESS_CAPABILITY_NETWORK) != 0;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isProcStateAllowedWhileInLowPowerStandby(@Nullable UidState uidState) {
|
||||
if (uidState == null) {
|
||||
return false;
|
||||
}
|
||||
return uidState.procState <= TOP_THRESHOLD_STATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -91,4 +91,10 @@ public abstract class NetworkPolicyManagerInternal {
|
||||
*/
|
||||
public abstract void setMeteredRestrictedPackagesAsync(
|
||||
Set<String> packageNames, int userId);
|
||||
|
||||
/** Informs that Low Power Standby has become active */
|
||||
public abstract void setLowPowerStandbyActive(boolean active);
|
||||
|
||||
/** Informs that the Low Power Standby allowlist has changed */
|
||||
public abstract void setLowPowerStandbyAllowlist(int[] uids);
|
||||
}
|
||||
|
||||
@@ -46,17 +46,19 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRI
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_RESTRICTED_MODE;
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||
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;
|
||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
|
||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
|
||||
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
|
||||
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
|
||||
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
|
||||
import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
|
||||
import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
|
||||
import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
|
||||
import static android.net.INetd.FIREWALL_RULE_ALLOW;
|
||||
import static android.net.INetd.FIREWALL_RULE_DENY;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||
@@ -69,11 +71,13 @@ import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP;
|
||||
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
||||
import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
|
||||
@@ -87,6 +91,7 @@ import static android.net.NetworkPolicyManager.RULE_REJECT_RESTRICTED_MODE;
|
||||
import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
|
||||
import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
|
||||
import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
|
||||
import static android.net.NetworkPolicyManager.isProcStateAllowedWhileInLowPowerStandby;
|
||||
import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
|
||||
import static android.net.NetworkPolicyManager.resolveNetworkId;
|
||||
import static android.net.NetworkPolicyManager.uidPoliciesToString;
|
||||
@@ -477,6 +482,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
volatile boolean mRestrictBackgroundChangedInBsm;
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
volatile boolean mRestrictedNetworkingMode;
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
volatile boolean mLowPowerStandbyActive;
|
||||
|
||||
private final boolean mSuppressDefaultPolicy;
|
||||
|
||||
@@ -516,6 +523,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
final SparseIntArray mUidFirewallRestrictedModeRules = new SparseIntArray();
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
final SparseIntArray mUidFirewallLowPowerStandbyModeRules = new SparseIntArray();
|
||||
|
||||
/** Set of states for the child firewall chains. True if the chain is active. */
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
@@ -544,6 +553,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
|
||||
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
private final SparseBooleanArray mLowPowerStandbyAllowlistUids = new SparseBooleanArray();
|
||||
|
||||
/**
|
||||
* UIDs that have been allowlisted temporarily to be able to have network access despite being
|
||||
* idle. Other power saving restrictions still apply.
|
||||
@@ -3785,6 +3797,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
fout.print("Restrict power: "); fout.println(mRestrictPower);
|
||||
fout.print("Device idle: "); fout.println(mDeviceIdleMode);
|
||||
fout.print("Restricted networking mode: "); fout.println(mRestrictedNetworkingMode);
|
||||
fout.print("Low Power Standby mode: "); fout.println(mLowPowerStandbyActive);
|
||||
synchronized (mMeteredIfacesLock) {
|
||||
fout.print("Metered ifaces: ");
|
||||
fout.println(mMeteredIfaces);
|
||||
@@ -3920,6 +3933,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
fout.decreaseIndent();
|
||||
}
|
||||
|
||||
size = mLowPowerStandbyAllowlistUids.size();
|
||||
if (size > 0) {
|
||||
fout.println("Low Power Standby allowlist uids:");
|
||||
fout.increaseIndent();
|
||||
for (int i = 0; i < size; i++) {
|
||||
fout.print("UID=");
|
||||
fout.print(mLowPowerStandbyAllowlistUids.keyAt(i));
|
||||
fout.println();
|
||||
}
|
||||
fout.decreaseIndent();
|
||||
}
|
||||
|
||||
final SparseBooleanArray knownUids = new SparseBooleanArray();
|
||||
collectKeys(mUidState, knownUids);
|
||||
collectKeys(mUidBlockedState, knownUids);
|
||||
@@ -4001,6 +4026,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
return isProcStateAllowedWhileIdleOrPowerSaveMode(uidState);
|
||||
}
|
||||
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
private boolean isUidTop(int uid) {
|
||||
final UidState uidState = mUidState.get(uid);
|
||||
return isProcStateAllowedWhileInLowPowerStandby(uidState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process state of UID changed; if needed, will trigger
|
||||
* {@link #updateRulesForDataUsageRestrictionsUL(int)} and
|
||||
@@ -4017,8 +4048,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
// state changed, push updated rules
|
||||
mUidState.put(uid, newUidState);
|
||||
updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, newUidState);
|
||||
if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
|
||||
!= isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState)) {
|
||||
boolean allowedWhileIdleOrPowerSaveModeChanged =
|
||||
isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
|
||||
!= isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState);
|
||||
if (allowedWhileIdleOrPowerSaveModeChanged) {
|
||||
updateRuleForAppIdleUL(uid);
|
||||
if (mDeviceIdleMode) {
|
||||
updateRuleForDeviceIdleUL(uid);
|
||||
@@ -4028,6 +4061,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
}
|
||||
updateRulesForPowerRestrictionsUL(uid);
|
||||
}
|
||||
if (mLowPowerStandbyActive) {
|
||||
boolean allowedInLpsChanged =
|
||||
isProcStateAllowedWhileInLowPowerStandby(oldUidState)
|
||||
!= isProcStateAllowedWhileInLowPowerStandby(newUidState);
|
||||
if (allowedInLpsChanged) {
|
||||
if (!allowedWhileIdleOrPowerSaveModeChanged) {
|
||||
updateRulesForPowerRestrictionsUL(uid);
|
||||
}
|
||||
updateRuleForLowPowerStandbyUL(uid);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} finally {
|
||||
@@ -4051,6 +4095,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
updateRuleForRestrictPowerUL(uid);
|
||||
}
|
||||
updateRulesForPowerRestrictionsUL(uid);
|
||||
if (mLowPowerStandbyActive) {
|
||||
updateRuleForLowPowerStandbyUL(uid);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4254,6 +4301,50 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
void updateRulesForLowPowerStandbyUL() {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForLowPowerStandbyUL");
|
||||
try {
|
||||
if (mLowPowerStandbyActive) {
|
||||
mUidFirewallLowPowerStandbyModeRules.clear();
|
||||
for (int i = mUidState.size() - 1; i >= 0; i--) {
|
||||
final int uid = mUidState.keyAt(i);
|
||||
UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
|
||||
if (hasInternetPermissionUL(uid) && uidBlockedState != null
|
||||
&& (uidBlockedState.effectiveBlockedReasons
|
||||
& BLOCKED_REASON_LOW_POWER_STANDBY) == 0) {
|
||||
mUidFirewallLowPowerStandbyModeRules.put(mUidBlockedState.keyAt(i),
|
||||
FIREWALL_RULE_ALLOW);
|
||||
}
|
||||
}
|
||||
setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY,
|
||||
mUidFirewallLowPowerStandbyModeRules, CHAIN_TOGGLE_ENABLE);
|
||||
} else {
|
||||
setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, null, CHAIN_TOGGLE_DISABLE);
|
||||
}
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
void updateRuleForLowPowerStandbyUL(int uid) {
|
||||
if (!hasInternetPermissionUL(uid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
|
||||
if (mUidState.contains(uid) && uidBlockedState != null
|
||||
&& (uidBlockedState.effectiveBlockedReasons & BLOCKED_REASON_LOW_POWER_STANDBY)
|
||||
== 0) {
|
||||
mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW);
|
||||
setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_ALLOW);
|
||||
} else {
|
||||
mUidFirewallLowPowerStandbyModeRules.delete(uid);
|
||||
setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a uid is allowlisted from power saving restrictions (eg: Battery Saver, Doze
|
||||
* mode, and app idle).
|
||||
@@ -4283,6 +4374,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
return mPowerSaveWhitelistExceptIdleAppIds.get(appId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a uid is allowlisted from low power standby restrictions.
|
||||
*/
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
private boolean isAllowlistedFromLowPowerStandbyUL(int uid) {
|
||||
return mLowPowerStandbyAllowlistUids.get(uid);
|
||||
}
|
||||
|
||||
// NOTE: since both fw_dozable and fw_powersave uses the same map
|
||||
// (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
|
||||
@GuardedBy("mUidRulesFirstLock")
|
||||
@@ -4620,6 +4719,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
mPowerSaveTempWhitelistAppIds.delete(uid);
|
||||
mAppIdleTempWhitelistAppIds.delete(uid);
|
||||
mUidFirewallRestrictedModeRules.delete(uid);
|
||||
mUidFirewallLowPowerStandbyModeRules.delete(uid);
|
||||
synchronized (mUidStateCallbackInfos) {
|
||||
mUidStateCallbackInfos.remove(uid);
|
||||
}
|
||||
@@ -4845,6 +4945,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
}
|
||||
|
||||
final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
|
||||
final boolean isTop = isUidTop(uid);
|
||||
|
||||
final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
|
||||
|
||||
@@ -4858,17 +4959,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
int newAllowedReasons = ALLOWED_REASON_NONE;
|
||||
newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0);
|
||||
newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0);
|
||||
newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0);
|
||||
newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
|
||||
newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
|
||||
|
||||
newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
|
||||
newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
|
||||
newAllowedReasons |= (isTop ? ALLOWED_REASON_TOP : 0);
|
||||
newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true)
|
||||
? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
|
||||
newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
|
||||
? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
|
||||
newAllowedReasons |= (uidBlockedState.allowedReasons
|
||||
& ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS);
|
||||
newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid))
|
||||
? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0;
|
||||
|
||||
uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
|
||||
& BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
|
||||
@@ -4890,6 +4995,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
+ ", mRestrictPower: " + mRestrictPower
|
||||
+ ", mDeviceIdleMode: " + mDeviceIdleMode
|
||||
+ ", isForeground=" + isForeground
|
||||
+ ", isTop=" + isTop
|
||||
+ ", isWhitelisted=" + isWhitelisted
|
||||
+ ", oldUidBlockedState=" + previousUidBlockedState.toString()
|
||||
+ ", newUidBlockedState=" + uidBlockedState.toString());
|
||||
@@ -5421,6 +5527,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
mUidFirewallPowerSaveRules.put(uid, rule);
|
||||
} else if (chain == FIREWALL_CHAIN_RESTRICTED) {
|
||||
mUidFirewallRestrictedModeRules.put(uid, rule);
|
||||
} else if (chain == FIREWALL_CHAIN_LOW_POWER_STANDBY) {
|
||||
mUidFirewallLowPowerStandbyModeRules.put(uid, rule);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -5468,6 +5576,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
.setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
|
||||
mNetworkManager
|
||||
.setFirewallUidRule(FIREWALL_CHAIN_RESTRICTED, uid, FIREWALL_RULE_DEFAULT);
|
||||
mNetworkManager
|
||||
.setFirewallUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid,
|
||||
FIREWALL_RULE_DEFAULT);
|
||||
mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
|
||||
mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
|
||||
} catch (IllegalStateException e) {
|
||||
@@ -5747,6 +5858,67 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
|
||||
userId, 0, packageNames).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLowPowerStandbyActive(boolean active) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setLowPowerStandbyActive");
|
||||
try {
|
||||
synchronized (mUidRulesFirstLock) {
|
||||
if (mLowPowerStandbyActive == active) {
|
||||
return;
|
||||
}
|
||||
mLowPowerStandbyActive = active;
|
||||
synchronized (mNetworkPoliciesSecondLock) {
|
||||
if (!mSystemReady) return;
|
||||
}
|
||||
|
||||
forEachUid("updateRulesForRestrictPower",
|
||||
uid -> updateRulesForPowerRestrictionsUL(uid));
|
||||
updateRulesForLowPowerStandbyUL();
|
||||
}
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLowPowerStandbyAllowlist(int[] uids) {
|
||||
synchronized (mUidRulesFirstLock) {
|
||||
final SparseBooleanArray changedUids = new SparseBooleanArray();
|
||||
for (int i = 0; i < mLowPowerStandbyAllowlistUids.size(); i++) {
|
||||
final int oldUid = mLowPowerStandbyAllowlistUids.keyAt(i);
|
||||
if (!ArrayUtils.contains(uids, oldUid)) {
|
||||
changedUids.put(oldUid, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < changedUids.size(); i++) {
|
||||
final int deletedUid = changedUids.keyAt(i);
|
||||
mLowPowerStandbyAllowlistUids.delete(deletedUid);
|
||||
}
|
||||
|
||||
for (int newUid : uids) {
|
||||
if (mLowPowerStandbyAllowlistUids.indexOfKey(newUid) < 0) {
|
||||
changedUids.append(newUid, true);
|
||||
mLowPowerStandbyAllowlistUids.append(newUid, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mLowPowerStandbyActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (mNetworkPoliciesSecondLock) {
|
||||
if (!mSystemReady) return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < changedUids.size(); i++) {
|
||||
final int changedUid = changedUids.keyAt(i);
|
||||
updateRulesForPowerRestrictionsUL(changedUid);
|
||||
updateRuleForLowPowerStandbyUL(changedUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) {
|
||||
@@ -5904,6 +6076,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
|
||||
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED;
|
||||
}
|
||||
if ((allowedReasons & ALLOWED_REASON_TOP) != 0) {
|
||||
effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY;
|
||||
}
|
||||
if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) {
|
||||
effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
|
||||
effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
|
||||
@@ -5919,6 +6094,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
|
||||
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
|
||||
}
|
||||
if ((allowedReasons & ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST) != 0) {
|
||||
effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY;
|
||||
}
|
||||
|
||||
return effectiveBlockedReasons;
|
||||
}
|
||||
|
||||
@@ -5943,6 +6122,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
BLOCKED_REASON_DOZE,
|
||||
BLOCKED_REASON_APP_STANDBY,
|
||||
BLOCKED_REASON_RESTRICTED_MODE,
|
||||
BLOCKED_REASON_LOW_POWER_STANDBY,
|
||||
BLOCKED_METERED_REASON_DATA_SAVER,
|
||||
BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
BLOCKED_METERED_REASON_ADMIN_DISABLED,
|
||||
@@ -5951,9 +6131,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
private static final int[] ALLOWED_REASONS = {
|
||||
ALLOWED_REASON_SYSTEM,
|
||||
ALLOWED_REASON_FOREGROUND,
|
||||
ALLOWED_REASON_TOP,
|
||||
ALLOWED_REASON_POWER_SAVE_ALLOWLIST,
|
||||
ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST,
|
||||
ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS,
|
||||
ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST,
|
||||
ALLOWED_METERED_REASON_USER_EXEMPTED,
|
||||
ALLOWED_METERED_REASON_SYSTEM,
|
||||
ALLOWED_METERED_REASON_FOREGROUND,
|
||||
@@ -5971,6 +6153,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
return "APP_STANDBY";
|
||||
case BLOCKED_REASON_RESTRICTED_MODE:
|
||||
return "RESTRICTED_MODE";
|
||||
case BLOCKED_REASON_LOW_POWER_STANDBY:
|
||||
return "LOW_POWER_STANDBY";
|
||||
case BLOCKED_METERED_REASON_DATA_SAVER:
|
||||
return "DATA_SAVER";
|
||||
case BLOCKED_METERED_REASON_USER_RESTRICTED:
|
||||
@@ -5991,12 +6175,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
return "SYSTEM";
|
||||
case ALLOWED_REASON_FOREGROUND:
|
||||
return "FOREGROUND";
|
||||
case ALLOWED_REASON_TOP:
|
||||
return "TOP";
|
||||
case ALLOWED_REASON_POWER_SAVE_ALLOWLIST:
|
||||
return "POWER_SAVE_ALLOWLIST";
|
||||
case ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST:
|
||||
return "POWER_SAVE_EXCEPT_IDLE_ALLOWLIST";
|
||||
case ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS:
|
||||
return "RESTRICTED_MODE_PERMISSIONS";
|
||||
case ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST:
|
||||
return "LOW_POWER_STANDBY_ALLOWLIST";
|
||||
case ALLOWED_METERED_REASON_USER_EXEMPTED:
|
||||
return "METERED_USER_EXEMPTED";
|
||||
case ALLOWED_METERED_REASON_SYSTEM:
|
||||
@@ -6063,7 +6251,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
|
||||
int powerBlockedReasons = BLOCKED_REASON_APP_STANDBY
|
||||
| BLOCKED_REASON_DOZE
|
||||
| BLOCKED_REASON_BATTERY_SAVER;
|
||||
| BLOCKED_REASON_BATTERY_SAVER
|
||||
| BLOCKED_REASON_LOW_POWER_STANDBY;
|
||||
if ((effectiveBlockedReasons & powerBlockedReasons) != 0) {
|
||||
uidRule |= RULE_REJECT_ALL;
|
||||
} else if ((blockedReasons & powerBlockedReasons) != 0) {
|
||||
|
||||
@@ -23,11 +23,13 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRI
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY;
|
||||
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
|
||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||
import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
|
||||
import static android.net.INetd.FIREWALL_RULE_ALLOW;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
@@ -38,8 +40,10 @@ import static android.net.NetworkPolicy.WARNING_DISABLED;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
|
||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP;
|
||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
||||
import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
|
||||
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
||||
@@ -200,6 +204,7 @@ import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -1876,56 +1881,100 @@ public class NetworkPolicyManagerServiceTest {
|
||||
assertFalse(mService.isUidNetworkingBlocked(UID_E, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowPowerStandbyAllowlist() throws Exception {
|
||||
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
|
||||
callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
|
||||
callOnUidStateChanged(UID_C, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
|
||||
expectHasInternetPermission(UID_A, true);
|
||||
expectHasInternetPermission(UID_B, true);
|
||||
expectHasInternetPermission(UID_C, true);
|
||||
|
||||
final NetworkPolicyManagerInternal internal = LocalServices
|
||||
.getService(NetworkPolicyManagerInternal.class);
|
||||
|
||||
Map<Integer, Integer> firewallUidRules = new ArrayMap<>();
|
||||
doAnswer(arg -> {
|
||||
int[] uids = arg.getArgument(1);
|
||||
int[] rules = arg.getArgument(2);
|
||||
assertTrue(uids.length == rules.length);
|
||||
|
||||
for (int i = 0; i < uids.length; ++i) {
|
||||
firewallUidRules.put(uids[i], rules[i]);
|
||||
}
|
||||
return null;
|
||||
}).when(mNetworkManager).setFirewallUidRules(eq(FIREWALL_CHAIN_LOW_POWER_STANDBY),
|
||||
any(int[].class), any(int[].class));
|
||||
|
||||
internal.setLowPowerStandbyAllowlist(new int[] { UID_B });
|
||||
internal.setLowPowerStandbyActive(true);
|
||||
assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_A).intValue());
|
||||
assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_B).intValue());
|
||||
assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
|
||||
assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
|
||||
assertTrue(mService.isUidNetworkingBlocked(UID_C, false));
|
||||
|
||||
internal.setLowPowerStandbyActive(false);
|
||||
assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
|
||||
assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
|
||||
assertFalse(mService.isUidNetworkingBlocked(UID_C, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateEffectiveBlockedReasons() {
|
||||
final SparseArray<Pair<Integer, Integer>> effectiveBlockedReasons = new SparseArray<>();
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE));
|
||||
final Map<Pair<Integer, Integer>, Integer> effectiveBlockedReasons = new HashMap<>();
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE),
|
||||
BLOCKED_REASON_NONE);
|
||||
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_SYSTEM));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE,
|
||||
ALLOWED_REASON_SYSTEM));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_METERED_REASON_DATA_SAVER,
|
||||
ALLOWED_METERED_REASON_SYSTEM));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_METERED_REASON_DATA_SAVER
|
||||
| BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_SYSTEM));
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_SYSTEM),
|
||||
BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE,
|
||||
ALLOWED_REASON_SYSTEM), BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_SYSTEM),
|
||||
BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_METERED_REASON_DATA_SAVER
|
||||
| BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_SYSTEM), BLOCKED_REASON_NONE);
|
||||
|
||||
effectiveBlockedReasons.put(BLOCKED_METERED_REASON_DATA_SAVER,
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER,
|
||||
ALLOWED_REASON_SYSTEM));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_APP_STANDBY,
|
||||
ALLOWED_REASON_SYSTEM), BLOCKED_METERED_REASON_DATA_SAVER);
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_REASON_APP_STANDBY | BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_SYSTEM));
|
||||
ALLOWED_METERED_REASON_SYSTEM), BLOCKED_REASON_APP_STANDBY);
|
||||
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_FOREGROUND));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE,
|
||||
ALLOWED_REASON_FOREGROUND));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_FOREGROUND));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_NONE,
|
||||
Pair.create(BLOCKED_METERED_REASON_DATA_SAVER
|
||||
| BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_FOREGROUND));
|
||||
effectiveBlockedReasons.put(BLOCKED_METERED_REASON_DATA_SAVER,
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_FOREGROUND),
|
||||
BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE,
|
||||
ALLOWED_REASON_FOREGROUND), BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_FOREGROUND),
|
||||
BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_METERED_REASON_DATA_SAVER
|
||||
| BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_FOREGROUND), BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER,
|
||||
ALLOWED_REASON_FOREGROUND));
|
||||
effectiveBlockedReasons.put(BLOCKED_REASON_BATTERY_SAVER,
|
||||
Pair.create(BLOCKED_REASON_BATTERY_SAVER
|
||||
| BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_FOREGROUND));
|
||||
ALLOWED_REASON_FOREGROUND), BLOCKED_METERED_REASON_DATA_SAVER);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER
|
||||
| BLOCKED_METERED_REASON_USER_RESTRICTED,
|
||||
ALLOWED_METERED_REASON_FOREGROUND), BLOCKED_REASON_BATTERY_SAVER);
|
||||
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY,
|
||||
ALLOWED_REASON_FOREGROUND), BLOCKED_REASON_LOW_POWER_STANDBY);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY,
|
||||
ALLOWED_REASON_TOP), BLOCKED_REASON_NONE);
|
||||
effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY,
|
||||
ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST), BLOCKED_REASON_NONE);
|
||||
// TODO: test more combinations of blocked reasons.
|
||||
|
||||
for (int i = 0; i < effectiveBlockedReasons.size(); ++i) {
|
||||
final int expectedEffectiveBlockedReasons = effectiveBlockedReasons.keyAt(i);
|
||||
final int blockedReasons = effectiveBlockedReasons.valueAt(i).first;
|
||||
final int allowedReasons = effectiveBlockedReasons.valueAt(i).second;
|
||||
for (Map.Entry<Pair<Integer, Integer>, Integer> test : effectiveBlockedReasons.entrySet()) {
|
||||
final int expectedEffectiveBlockedReasons = test.getValue();
|
||||
final int blockedReasons = test.getKey().first;
|
||||
final int allowedReasons = test.getKey().second;
|
||||
final String errorMsg = "Expected="
|
||||
+ blockedReasonsToString(expectedEffectiveBlockedReasons)
|
||||
+ "; blockedReasons=" + blockedReasonsToString(blockedReasons)
|
||||
|
||||
Reference in New Issue
Block a user