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

Commit 03e95e2f authored by Felipe Leme's avatar Felipe Leme
Browse files

NPMS: Cleaned up UID removal code.

When an UID is removed, NPMS needs to perform 2 tasks:

- Removed internal state associated with the UID.
- Call NMS to reset the iptables rules associated with the UID.

Currently, the UID removal logic is intermingled with code used used
during the UID state path, which has 3 drawbacks:

- Adds unnecessary comparisons.
- Makes the code more complicated.
- Is not handling all scenarios (like removing UID from fw_standby).

This CL simplifies how these 2 tasks are achieved.

Test: m -j32 cts && cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests

Change-Id: I12e9a6777b0d7168751571889fd7bb2d13934745
Fixes: 31377000
parent 3fbaf383
Loading
Loading
Loading
Loading
+46 −17
Original line number Diff line number Diff line
@@ -292,6 +292,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
    private static final int MSG_POLICIES_CHANGED = 13;
    private static final int MSG_SET_FIREWALL_RULES = 14;
    private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;

    private final Context mContext;
    private final IActivityManager mActivityManager;
@@ -737,7 +738,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                // global background data policy
                if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
                synchronized (mUidRulesFirstLock) {
                    updateRestrictionRulesForUidUL(uid, false);
                    updateRestrictionRulesForUidUL(uid);
                }
            }
        }
@@ -754,11 +755,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            // remove any policy and update rules to clean up
            if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
            synchronized (mUidRulesFirstLock) {
                mUidRules.delete(uid);
                mUidPolicy.delete(uid);
                // TODO: rather than passing onUidDeleted=true, it would be clearner to have a
                // method that reset all firewall rules for an UID....
                updateRestrictionRulesForUidUL(uid, true);
                onUidDeletedUL(uid);
                synchronized (mNetworkPoliciesSecondLock) {
                    writePolicyAL();
                }
@@ -2810,6 +2807,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        return true;
    }

    /**
     * Clears all state - internal and external - associated with an UID.
     */
    private void onUidDeletedUL(int uid) {
        // First cleanup in-memory state synchronously...
        mUidRules.delete(uid);
        mUidPolicy.delete(uid);
        mUidFirewallStandbyRules.delete(uid);
        mUidFirewallDozableRules.delete(uid);
        mUidFirewallPowerSaveRules.delete(uid);
        mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
        mPowerSaveWhitelistAppIds.delete(uid);
        mPowerSaveTempWhitelistAppIds.delete(uid);

        // ...then update iptables asynchronously.
        mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
    }

    /**
     * Applies network rules to bandwidth and firewall controllers based on uid policy.
     *
@@ -2823,7 +2838,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
     *
     * <p>This method changes both the external firewall rules and the internal state.
     */
    private void updateRestrictionRulesForUidUL(int uid, boolean onUidDeleted) {
    private void updateRestrictionRulesForUidUL(int uid) {
        // Methods below only changes the firewall rules for the power-related modes.
        updateRuleForDeviceIdleUL(uid);
        updateRuleForAppIdleUL(uid);
@@ -2833,7 +2848,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        updateRulesForPowerRestrictionsUL(uid);

        // Update firewall and internal rules for Data Saver Mode.
        updateRulesForDataUsageRestrictionsUL(uid, onUidDeleted);
        updateRulesForDataUsageRestrictionsUL(uid);
    }

    /**
@@ -2876,15 +2891,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
     *
     */
    private void updateRulesForDataUsageRestrictionsUL(int uid) {
        updateRulesForDataUsageRestrictionsUL(uid, false);
    }

    /**
     * Overloaded version of {@link #updateRulesForDataUsageRestrictionsUL(int)} called when an
     * app is removed - it ignores the UID validity check.
     */
    private void updateRulesForDataUsageRestrictionsUL(int uid, boolean onUidDeleted) {
        if (!onUidDeleted && !isUidValidForWhitelistRules(uid)) {
        if (!isUidValidForWhitelistRules(uid)) {
            if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
            return;
        }
@@ -3265,6 +3272,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                    }
                    return true;
                }
                case MSG_RESET_FIREWALL_RULES_BY_UID: {
                    resetUidFirewallRules(msg.arg1);
                    return true;
                }
                default: {
                    return false;
                }
@@ -3417,6 +3428,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        }
    }

    /**
     * Resets all firewall rules associated with an UID.
     */
    private void resetUidFirewallRules(int uid) {
        try {
            mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
            mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
            mNetworkManager
                    .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
            mNetworkManager.setUidMeteredNetworkWhitelist(uid, false);
            mNetworkManager.setUidMeteredNetworkBlacklist(uid, false);
        } catch (IllegalStateException e) {
            Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
        } catch (RemoteException e) {
            // ignored; service lives in system_server
        }
    }

    private long getTotalBytes(NetworkTemplate template, long start, long end) {
        try {
            return mNetworkStats.getNetworkTotalBytes(template, start, end);