Merge changes from topic "restricted-mode-cts"
* changes: Prevent clearing Restricted Mode uid state when other rules change Add shell command to query Restricted Mode state Add Restricted Mode settings observer to NetworkPolicyManagerService
This commit is contained in:
@@ -149,6 +149,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.database.ContentObserver;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.IConnectivityManager;
|
import android.net.IConnectivityManager;
|
||||||
@@ -609,6 +610,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
@GuardedBy("mUidRulesFirstLock")
|
@GuardedBy("mUidRulesFirstLock")
|
||||||
private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
|
private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
|
||||||
|
|
||||||
|
private RestrictedModeObserver mRestrictedModeObserver;
|
||||||
|
|
||||||
// TODO: keep allowlist of system-critical services that should never have
|
// TODO: keep allowlist of system-critical services that should never have
|
||||||
// rules enforced, such as system, phone, and radio UIDs.
|
// rules enforced, such as system, phone, and radio UIDs.
|
||||||
|
|
||||||
@@ -622,7 +625,35 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
|
int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final StatLogger mStatLogger = new StatLogger(new String[] {
|
private static class RestrictedModeObserver extends ContentObserver {
|
||||||
|
private final Context mContext;
|
||||||
|
private final RestrictedModeListener mListener;
|
||||||
|
|
||||||
|
RestrictedModeObserver(Context ctx, RestrictedModeListener listener) {
|
||||||
|
super(null);
|
||||||
|
mContext = ctx;
|
||||||
|
mListener = listener;
|
||||||
|
mContext.getContentResolver().registerContentObserver(
|
||||||
|
Settings.Global.getUriFor(Settings.Global.RESTRICTED_NETWORKING_MODE), false,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRestrictedModeEnabled() {
|
||||||
|
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
|
Settings.Global.RESTRICTED_NETWORKING_MODE, 0) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
mListener.onChange(isRestrictedModeEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface RestrictedModeListener {
|
||||||
|
void onChange(boolean enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final StatLogger mStatLogger = new StatLogger(new String[]{
|
||||||
"updateNetworkEnabledNL()",
|
"updateNetworkEnabledNL()",
|
||||||
"isUidNetworkingBlocked()",
|
"isUidNetworkingBlocked()",
|
||||||
});
|
});
|
||||||
@@ -797,9 +828,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
mRestrictPower = mPowerManagerInternal.getLowPowerState(
|
mRestrictPower = mPowerManagerInternal.getLowPowerState(
|
||||||
ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
|
ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
|
||||||
|
|
||||||
mRestrictedNetworkingMode = Settings.Global.getInt(
|
mRestrictedModeObserver = new RestrictedModeObserver(mContext,
|
||||||
mContext.getContentResolver(),
|
enabled -> {
|
||||||
Settings.Global.RESTRICTED_NETWORKING_MODE, 0) != 0;
|
synchronized (mUidRulesFirstLock) {
|
||||||
|
mRestrictedNetworkingMode = enabled;
|
||||||
|
updateRestrictedModeAllowlistUL();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mRestrictedNetworkingMode = mRestrictedModeObserver.isRestrictedModeEnabled();
|
||||||
|
|
||||||
mSystemReady = true;
|
mSystemReady = true;
|
||||||
|
|
||||||
@@ -3828,6 +3864,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isRestrictedModeEnabled() {
|
||||||
|
synchronized (mUidRulesFirstLock) {
|
||||||
|
return mRestrictedNetworkingMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates restricted mode state / access for all apps
|
* updates restricted mode state / access for all apps
|
||||||
* Called on initialization and when restricted mode is enabled / disabled.
|
* Called on initialization and when restricted mode is enabled / disabled.
|
||||||
@@ -4455,26 +4498,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
|
|
||||||
final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
|
final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
|
||||||
final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
|
final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
|
||||||
final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
|
|
||||||
int newRule = RULE_NONE;
|
// copy oldUidRules and clear out METERED_NETWORKS rules.
|
||||||
|
int newUidRules = oldUidRules & (~MASK_METERED_NETWORKS);
|
||||||
|
|
||||||
// First step: define the new rule based on user restrictions and foreground state.
|
// First step: define the new rule based on user restrictions and foreground state.
|
||||||
if (isRestrictedByAdmin) {
|
if (isRestrictedByAdmin) {
|
||||||
newRule = RULE_REJECT_METERED;
|
newUidRules |= RULE_REJECT_METERED;
|
||||||
} else if (isForeground) {
|
} else if (isForeground) {
|
||||||
if (isDenied || (mRestrictBackground && !isAllowed)) {
|
if (isDenied || (mRestrictBackground && !isAllowed)) {
|
||||||
newRule = RULE_TEMPORARY_ALLOW_METERED;
|
newUidRules |= RULE_TEMPORARY_ALLOW_METERED;
|
||||||
} else if (isAllowed) {
|
} else if (isAllowed) {
|
||||||
newRule = RULE_ALLOW_METERED;
|
newUidRules |= RULE_ALLOW_METERED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isDenied) {
|
if (isDenied) {
|
||||||
newRule = RULE_REJECT_METERED;
|
newUidRules |= RULE_REJECT_METERED;
|
||||||
} else if (mRestrictBackground && isAllowed) {
|
} else if (mRestrictBackground && isAllowed) {
|
||||||
newRule = RULE_ALLOW_METERED;
|
newUidRules |= RULE_ALLOW_METERED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
|
|
||||||
|
|
||||||
if (LOGV) {
|
if (LOGV) {
|
||||||
Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
|
Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
|
||||||
@@ -4482,8 +4525,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
+ ", isDenied=" + isDenied
|
+ ", isDenied=" + isDenied
|
||||||
+ ", isAllowed=" + isAllowed
|
+ ", isAllowed=" + isAllowed
|
||||||
+ ", isRestrictedByAdmin=" + isRestrictedByAdmin
|
+ ", isRestrictedByAdmin=" + isRestrictedByAdmin
|
||||||
+ ", oldRule=" + uidRulesToString(oldRule)
|
+ ", oldRule=" + uidRulesToString(oldUidRules & MASK_METERED_NETWORKS)
|
||||||
+ ", newRule=" + uidRulesToString(newRule)
|
+ ", newRule=" + uidRulesToString(newUidRules & MASK_METERED_NETWORKS)
|
||||||
+ ", newUidRules=" + uidRulesToString(newUidRules)
|
+ ", newUidRules=" + uidRulesToString(newUidRules)
|
||||||
+ ", oldUidRules=" + uidRulesToString(oldUidRules));
|
+ ", oldUidRules=" + uidRulesToString(oldUidRules));
|
||||||
}
|
}
|
||||||
@@ -4495,8 +4538,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Second step: apply bw changes based on change of state.
|
// Second step: apply bw changes based on change of state.
|
||||||
if (newRule != oldRule) {
|
if (newUidRules != oldUidRules) {
|
||||||
if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
|
if (hasRule(newUidRules, RULE_TEMPORARY_ALLOW_METERED)) {
|
||||||
// Temporarily allow foreground app, removing from denylist if necessary
|
// Temporarily allow foreground app, removing from denylist if necessary
|
||||||
// (since bw_penalty_box prevails over bw_happy_box).
|
// (since bw_penalty_box prevails over bw_happy_box).
|
||||||
|
|
||||||
@@ -4507,7 +4550,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
if (isDenied) {
|
if (isDenied) {
|
||||||
setMeteredNetworkDenylist(uid, false);
|
setMeteredNetworkDenylist(uid, false);
|
||||||
}
|
}
|
||||||
} else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
|
} else if (hasRule(oldUidRules, RULE_TEMPORARY_ALLOW_METERED)) {
|
||||||
// Remove temporary exemption from app that is not on foreground anymore.
|
// Remove temporary exemption from app that is not on foreground anymore.
|
||||||
|
|
||||||
// TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
|
// TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
|
||||||
@@ -4520,18 +4563,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
if (isDenied || isRestrictedByAdmin) {
|
if (isDenied || isRestrictedByAdmin) {
|
||||||
setMeteredNetworkDenylist(uid, true);
|
setMeteredNetworkDenylist(uid, true);
|
||||||
}
|
}
|
||||||
} else if (hasRule(newRule, RULE_REJECT_METERED)
|
} else if (hasRule(newUidRules, RULE_REJECT_METERED)
|
||||||
|| hasRule(oldRule, RULE_REJECT_METERED)) {
|
|| hasRule(oldUidRules, RULE_REJECT_METERED)) {
|
||||||
// Flip state because app was explicitly added or removed to denylist.
|
// Flip state because app was explicitly added or removed to denylist.
|
||||||
setMeteredNetworkDenylist(uid, (isDenied || isRestrictedByAdmin));
|
setMeteredNetworkDenylist(uid, (isDenied || isRestrictedByAdmin));
|
||||||
if (hasRule(oldRule, RULE_REJECT_METERED) && isAllowed) {
|
if (hasRule(oldUidRules, RULE_REJECT_METERED) && isAllowed) {
|
||||||
// Since denial prevails over allowance, we need to handle the special case
|
// Since denial prevails over allowance, we need to handle the special case
|
||||||
// where app is allowed and denied at the same time (although such
|
// where app is allowed and denied at the same time (although such
|
||||||
// scenario should be blocked by the UI), then it is removed from the denylist.
|
// scenario should be blocked by the UI), then it is removed from the denylist.
|
||||||
setMeteredNetworkAllowlist(uid, isAllowed);
|
setMeteredNetworkAllowlist(uid, isAllowed);
|
||||||
}
|
}
|
||||||
} else if (hasRule(newRule, RULE_ALLOW_METERED)
|
} else if (hasRule(newUidRules, RULE_ALLOW_METERED)
|
||||||
|| hasRule(oldRule, RULE_ALLOW_METERED)) {
|
|| hasRule(oldUidRules, RULE_ALLOW_METERED)) {
|
||||||
// Flip state because app was explicitly added or removed to allowlist.
|
// Flip state because app was explicitly added or removed to allowlist.
|
||||||
setMeteredNetworkAllowlist(uid, isAllowed);
|
setMeteredNetworkAllowlist(uid, isAllowed);
|
||||||
} else {
|
} else {
|
||||||
@@ -4617,8 +4660,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
|
final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
|
||||||
|
|
||||||
final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
|
final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
|
||||||
final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
|
|
||||||
int newRule = RULE_NONE;
|
// Copy existing uid rules and clear ALL_NETWORK rules.
|
||||||
|
int newUidRules = oldUidRules & (~MASK_ALL_NETWORKS);
|
||||||
|
|
||||||
// First step: define the new rule based on user restrictions and foreground state.
|
// First step: define the new rule based on user restrictions and foreground state.
|
||||||
|
|
||||||
@@ -4626,14 +4670,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
// by considering the foreground and non-foreground states.
|
// by considering the foreground and non-foreground states.
|
||||||
if (isForeground) {
|
if (isForeground) {
|
||||||
if (restrictMode) {
|
if (restrictMode) {
|
||||||
newRule = RULE_ALLOW_ALL;
|
newUidRules |= RULE_ALLOW_ALL;
|
||||||
}
|
}
|
||||||
} else if (restrictMode) {
|
} else if (restrictMode) {
|
||||||
newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
|
newUidRules |= isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
|
|
||||||
|
|
||||||
if (LOGV) {
|
if (LOGV) {
|
||||||
Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
|
Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
|
||||||
+ ", isIdle: " + isUidIdle
|
+ ", isIdle: " + isUidIdle
|
||||||
@@ -4641,17 +4683,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
+ ", mDeviceIdleMode: " + mDeviceIdleMode
|
+ ", mDeviceIdleMode: " + mDeviceIdleMode
|
||||||
+ ", isForeground=" + isForeground
|
+ ", isForeground=" + isForeground
|
||||||
+ ", isWhitelisted=" + isWhitelisted
|
+ ", isWhitelisted=" + isWhitelisted
|
||||||
+ ", oldRule=" + uidRulesToString(oldRule)
|
+ ", oldRule=" + uidRulesToString(oldUidRules & MASK_ALL_NETWORKS)
|
||||||
+ ", newRule=" + uidRulesToString(newRule)
|
+ ", newRule=" + uidRulesToString(newUidRules & MASK_ALL_NETWORKS)
|
||||||
+ ", newUidRules=" + uidRulesToString(newUidRules)
|
+ ", newUidRules=" + uidRulesToString(newUidRules)
|
||||||
+ ", oldUidRules=" + uidRulesToString(oldUidRules));
|
+ ", oldUidRules=" + uidRulesToString(oldUidRules));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second step: notify listeners if state changed.
|
// Second step: notify listeners if state changed.
|
||||||
if (newRule != oldRule) {
|
if (newUidRules != oldUidRules) {
|
||||||
if (newRule == RULE_NONE || hasRule(newRule, RULE_ALLOW_ALL)) {
|
if ((newUidRules & MASK_ALL_NETWORKS) == RULE_NONE || hasRule(newUidRules,
|
||||||
|
RULE_ALLOW_ALL)) {
|
||||||
if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
|
if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
|
||||||
} else if (hasRule(newRule, RULE_REJECT_ALL)) {
|
} else if (hasRule(newUidRules, RULE_REJECT_ALL)) {
|
||||||
if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
|
if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
|
||||||
} else {
|
} else {
|
||||||
// All scenarios should have been covered above
|
// All scenarios should have been covered above
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ class NetworkPolicyManagerShellCommand extends ShellCommand {
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case "restrict-background":
|
case "restrict-background":
|
||||||
return getRestrictBackground();
|
return getRestrictBackground();
|
||||||
|
case "restricted-mode":
|
||||||
|
return getRestrictedModeState();
|
||||||
}
|
}
|
||||||
pw.println("Error: unknown get type '" + type + "'");
|
pw.println("Error: unknown get type '" + type + "'");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -255,6 +257,13 @@ class NetworkPolicyManagerShellCommand extends ShellCommand {
|
|||||||
return listUidList("App Idle whitelisted UIDs", uids);
|
return listUidList("App Idle whitelisted UIDs", uids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getRestrictedModeState() {
|
||||||
|
final PrintWriter pw = getOutPrintWriter();
|
||||||
|
pw.print("Restricted mode status: ");
|
||||||
|
pw.println(mInterface.isRestrictedModeEnabled() ? "enabled" : "disabled");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private int getRestrictBackground() throws RemoteException {
|
private int getRestrictBackground() throws RemoteException {
|
||||||
final PrintWriter pw = getOutPrintWriter();
|
final PrintWriter pw = getOutPrintWriter();
|
||||||
pw.print("Restrict background status: ");
|
pw.print("Restrict background status: ");
|
||||||
|
|||||||
Reference in New Issue
Block a user