Consider allow-in-power-save-except-idle whitelist while updating rules.

Fixes: 37670935
Test: manual &&
      runtest -c com.android.server.NetworkPolicyManagerServiceTest frameworks-services
      cts-tradefed run singleCommand cts-dev -m CtsHostsideNetworkTests -t \
            com.android.cts.net.HostsideRestrictBackgroundNetworkTests
Change-Id: I3520ed24147b9b6dd9e7b19aa9a90dd8c0b371ad
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 39585a1..bd5a516 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2879,17 +2879,11 @@
             final List<UserInfo> users = mUserManager.getUsers();
             for (int ui = users.size() - 1; ui >= 0; ui--) {
                 UserInfo user = users.get(ui);
-                for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
-                    if (mPowerSaveTempWhitelistAppIds.valueAt(i)) {
-                        int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
-                        int uid = UserHandle.getUid(user.id, appId);
-                        uidRules.put(uid, FIREWALL_RULE_ALLOW);
-                    }
-                }
-                for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
-                    int appId = mPowerSaveWhitelistAppIds.keyAt(i);
-                    int uid = UserHandle.getUid(user.id, appId);
-                    uidRules.put(uid, FIREWALL_RULE_ALLOW);
+                updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
+                updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
+                if (chain == FIREWALL_CHAIN_POWERSAVE) {
+                    updateRulesForWhitelistedAppIds(uidRules,
+                            mPowerSaveWhitelistExceptIdleAppIds, user.id);
                 }
             }
             for (int i = mUidState.size() - 1; i >= 0; i--) {
@@ -2903,16 +2897,39 @@
         }
     }
 
-    private boolean isWhitelistedBatterySaverUL(int uid) {
+    private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
+            final SparseBooleanArray whitelistedAppIds, int userId) {
+        for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
+            if (whitelistedAppIds.valueAt(i)) {
+                final int appId = whitelistedAppIds.keyAt(i);
+                final int uid = UserHandle.getUid(userId, appId);
+                uidRules.put(uid, FIREWALL_RULE_ALLOW);
+            }
+        }
+    }
+
+    /**
+     * @param deviceIdleMode if true then we don't consider
+     *        {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
+     *        whitelisted.
+     */
+    private boolean isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode) {
         final int appId = UserHandle.getAppId(uid);
-        return mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId);
+        boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
+                || mPowerSaveWhitelistAppIds.get(appId);
+        if (!deviceIdleMode) {
+            isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
+        }
+        return isWhitelisted;
     }
 
     // NOTE: since both fw_dozable and fw_powersave uses the same map
     // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
     private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
         if (enabled) {
-            if (isWhitelistedBatterySaverUL(uid) || isUidForegroundOnRestrictPowerUL(uid)) {
+            final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid,
+                    chain == FIREWALL_CHAIN_DOZABLE);
+            if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
                 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
             } else {
                 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
@@ -3430,7 +3447,7 @@
         final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
         final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
 
-        final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid);
+        final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode);
         final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
         int newRule = RULE_NONE;