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

Unverified Commit 91d0faa4 authored by Tommy Webb's avatar Tommy Webb Committed by Michael Bestas
Browse files

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
parent 01d72328
Loading
Loading
Loading
Loading
+59 −13
Original line number Diff line number Diff line
@@ -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;
    }