Add cts to test power-save-except-idle whitelist is correctly used.

Bug: 37670935
Test: cts-tradefed run singleCommand cts-dev -m CtsHostsideNetworkTests -t \
      com.android.cts.net.HostsideRestrictBackgroundNetworkTests
Change-Id: I03619bec15e14707ab103c77feab08d3520a2914
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
index 0f2965c..d2c0873 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -32,6 +32,7 @@
 
         // Set initial state.
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
         setAppIdle(false);
         turnBatteryOff();
 
@@ -111,6 +112,14 @@
         assertAppIdle(true); // Sanity check - idle again, once whitelisted was removed
         assertBackgroundNetworkAccess(false);
 
+        addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+        assertAppIdle(false); // Sanity check - not idle anymore, since whitelisted
+        assertBackgroundNetworkAccess(true);
+
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+        assertAppIdle(true); // Sanity check - idle again, once whitelisted was removed
+        assertBackgroundNetworkAccess(false);
+
         assertsForegroundAlwaysHasNetworkAccess();
 
         // Sanity check - no whitelist, no access!
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
index 60253f9..28175b8 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
@@ -31,6 +31,7 @@
 
         // Set initial state.
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
         setBatterySaverMode(false);
 
         registerBroadcastReceiver();
@@ -121,6 +122,12 @@
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
         assertBackgroundNetworkAccess(false);
 
+        addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(true);
+
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(false);
+
         assertsForegroundAlwaysHasNetworkAccess();
         assertBackgroundNetworkAccess(false);
     }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
index baeaa47..c2dce38 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
@@ -32,6 +32,7 @@
 
         // Set initial state.
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
         setDozeMode(false);
 
         registerBroadcastReceiver();
@@ -107,6 +108,12 @@
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
         assertBackgroundNetworkAccess(false);
 
+        addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(false);
+
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(false);
+
         assertsForegroundAlwaysHasNetworkAccess();
         assertBackgroundNetworkAccess(false);
     }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 577f62c..c672b31 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -695,6 +695,31 @@
         assertPowerSaveModeWhitelist(packageName, false); // Sanity check
     }
 
+    protected void assertPowerSaveModeExceptIdleWhitelist(String packageName, boolean expected)
+            throws Exception {
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        assertDelayedShellCommand("dumpsys deviceidle except-idle-whitelist =" + packageName,
+                Boolean.toString(expected));
+    }
+
+    protected void addPowerSaveModeExceptIdleWhitelist(String packageName) throws Exception {
+        Log.i(TAG, "Adding package " + packageName + " to power-save-mode-except-idle whitelist");
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        executeShellCommand("dumpsys deviceidle except-idle-whitelist +" + packageName);
+        assertPowerSaveModeExceptIdleWhitelist(packageName, true); // Sanity check
+    }
+
+    protected void removePowerSaveModeExceptIdleWhitelist(String packageName) throws Exception {
+        Log.i(TAG, "Removing package " + packageName
+                + " from power-save-mode-except-idle whitelist");
+        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
+        // need to use netpolicy for whitelisting
+        executeShellCommand("dumpsys deviceidle except-idle-whitelist reset");
+        assertPowerSaveModeExceptIdleWhitelist(packageName, false); // Sanity check
+    }
+
     protected void turnBatteryOff() throws Exception {
         executeSilentShellCommand("cmd battery unplug");
     }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
index ec49eee..5248255 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
@@ -38,6 +38,7 @@
         removeRestrictBackgroundWhitelist(mUid);
         removeRestrictBackgroundBlacklist(mUid);
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
 
         registerBroadcastReceiver();
     }
@@ -200,4 +201,74 @@
         removeRestrictBackgroundBlacklist(mUid);
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
     }
+
+    /**
+     * Tests that powersave whitelists works as expected when doze and battery saver modes
+     * are enabled.
+     */
+    public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception {
+        if (!isSupported()) {
+            return;
+        }
+        if (!isDozeModeEnabled()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Doze Mode");
+            return;
+        }
+
+        setBatterySaverMode(true);
+        setDozeMode(true);
+
+        try {
+            addPowerSaveModeWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(true);
+
+            removePowerSaveModeWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(false);
+
+            addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(false);
+
+            removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(false);
+        } finally {
+            setBatterySaverMode(false);
+            setDozeMode(false);
+        }
+    }
+
+    /**
+     * Tests that powersave whitelists works as expected when doze and appIdle modes
+     * are enabled.
+     */
+    public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception {
+        if (!isSupported()) {
+            return;
+        }
+        if (!isDozeModeEnabled()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Doze Mode");
+            return;
+        }
+
+        setDozeMode(true);
+        setAppIdle(true);
+
+        try {
+            addPowerSaveModeWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(true);
+
+            removePowerSaveModeWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(false);
+
+            addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(false);
+
+            removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
+            assertBackgroundNetworkAccess(false);
+        } finally {
+            setAppIdle(false);
+            setDozeMode(false);
+        }
+    }
 }
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index faf75d9..bf3fc08 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -251,6 +251,16 @@
                 "testDataAndBatterySaverModes_nonMeteredNetwork");
     }
 
+    public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+                "testDozeAndBatterySaverMode_powerSaveWhitelists");
+    }
+
+    public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+                "testDozeAndAppIdle_powerSaveWhitelists");
+    }
+
     /*******************
      * Helper methods. *
      *******************/