Fix background data clobbering other policies

Stop removing preexisting UID policies when toggling
Background network access / unrestricted data usage.

Fetching the state of policies was not working due to an incorrect use
of Arrays.asList() - if you give it an int array, you just get a list
with that int[] as a single element, so using the contains method with
an int will always return false. This has now all been refactored.

Test: Manual: Open Settings > Network & Internet > Data Saver >
Unrestricted data. Turn it on for something. Go back, and then
return to the page. It should still show as on.

Issue: calyxos#2547
Issue: calyxos#2118
Change-Id2: I671544f6fdf9897484c6265c31c8b3cd29ad4a92
Change-Id: If54d0a0925c5da0f3d519d0a85491ff3b7b62351
This commit is contained in:
Tommy Webb
2024-02-21 15:28:28 +00:00
committed by Michael Bestas
parent b5b0168bdc
commit 9c0141b6d7

View File

@@ -82,8 +82,7 @@ public class DataSaverBackend {
}
public void setIsAllowlisted(int uid, String packageName, boolean allowlisted) {
final int policy = allowlisted ? POLICY_ALLOW_METERED_BACKGROUND : POLICY_NONE;
mUidPolicies.put(uid, policy);
setUidPolicyFlag(uid, POLICY_ALLOW_METERED_BACKGROUND, allowlisted);
if (allowlisted) {
mPolicyManager.addUidPolicy(uid, POLICY_ALLOW_METERED_BACKGROUND);
mMetricsFeatureProvider.action(
@@ -96,17 +95,14 @@ public class DataSaverBackend {
public boolean isAllowlisted(int uid) {
loadAllowlist();
return mUidPolicies.get(uid, POLICY_NONE) == POLICY_ALLOW_METERED_BACKGROUND;
return isUidPolicyFlagSet(uid, POLICY_ALLOW_METERED_BACKGROUND);
}
private void loadAllowlist() {
if (mAllowlistInitialized) {
return;
}
for (int uid : mPolicyManager.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND)) {
mUidPolicies.put(uid, POLICY_ALLOW_METERED_BACKGROUND);
}
loadUidPolicies(POLICY_ALLOW_METERED_BACKGROUND);
mAllowlistInitialized = true;
}
@@ -115,8 +111,7 @@ public class DataSaverBackend {
}
public void setIsDenylisted(int uid, String packageName, boolean denylisted) {
final int policy = denylisted ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE;
mUidPolicies.put(uid, policy);
setUidPolicyFlag(uid, POLICY_REJECT_METERED_BACKGROUND, denylisted);
if (denylisted) {
mPolicyManager.addUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND);
mMetricsFeatureProvider.action(
@@ -127,18 +122,69 @@ public class DataSaverBackend {
mPolicyManager.removeUidPolicy(uid, POLICY_ALLOW_METERED_BACKGROUND);
}
private void loadUidPolicies(int policy) {
final int[] uidsWithPolicyArray = mPolicyManager.getUidsWithPolicy(policy);
final ArrayList<Integer> uidsWithPolicy = new ArrayList<>(uidsWithPolicyArray.length);
for (final int uid : uidsWithPolicyArray) {
uidsWithPolicy.add(uid);
}
// Update existing cached UID policies.
for (int i = 0; i < mUidPolicies.size(); i++) {
final Integer cachedEntryUid = mUidPolicies.keyAt(i);
if (uidsWithPolicy.remove(cachedEntryUid)) {
// UID had the policy. It was removed so we don't have to process it twice.
setCachedUidPolicyFlagAt(i, policy, true);
} else {
// UID does not have the policy.
setCachedUidPolicyFlagAt(i, policy, false);
}
}
// Add policies for remaining UIDs, which did not have cached policies, so we're it.
for (final int uid : uidsWithPolicy) {
mUidPolicies.put(uid, policy);
}
}
private void setCachedUidPolicyFlag(int uid, int policy, boolean add) {
final int index = mUidPolicies.indexOfKey(uid);
if (index < 0) {
if (add) {
mUidPolicies.put(uid, policy);
}
return;
}
setCachedUidPolicyFlagAt(index, policy, add);
}
private void setCachedUidPolicyFlagAt(int index, int policy, boolean add) {
final int currentPolicy = mUidPolicies.valueAt(index);
final int newPolicy = add ? (currentPolicy | policy) : (currentPolicy & ~policy);
mUidPolicies.setValueAt(index, newPolicy);
}
private void setUidPolicyFlag(int uid, int policy, boolean add) {
if (add) {
mPolicyManager.addUidPolicy(uid, policy);
} else {
mPolicyManager.removeUidPolicy(uid, policy);
}
setCachedUidPolicyFlag(uid, policy, add);
}
private boolean isUidPolicyFlagSet(int uid, int policy) {
return (mUidPolicies.get(uid, POLICY_NONE) & policy) == policy;
}
public boolean isDenylisted(int uid) {
loadDenylist();
return mUidPolicies.get(uid, POLICY_NONE) == POLICY_REJECT_METERED_BACKGROUND;
return isUidPolicyFlagSet(uid, POLICY_REJECT_METERED_BACKGROUND);
}
private void loadDenylist() {
if (mDenylistInitialized) {
return;
}
for (int uid : mPolicyManager.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
mUidPolicies.put(uid, POLICY_REJECT_METERED_BACKGROUND);
}
loadUidPolicies(POLICY_REJECT_METERED_BACKGROUND);
mDenylistInitialized = true;
}