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 7d30056be1..defea4c0d3 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 @@ -897,4 +897,15 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { */ String getExpected(); } + + protected void setRestrictedNetworkingMode(boolean enabled) throws Exception { + executeSilentShellCommand( + "settings put global restricted_networking_mode " + (enabled ? 1 : 0)); + assertRestrictedNetworkingModeState(enabled); + } + + protected void assertRestrictedNetworkingModeState(boolean enabled) throws Exception { + assertDelayedShellCommand("cmd netpolicy get restricted-mode", + "Restricted mode status: " + (enabled ? "enabled" : "disabled")); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java new file mode 100644 index 0000000000..ddc5fd4357 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.cts.net.hostside; + +import static android.os.Process.SYSTEM_UID; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.assertNetworkingBlockedStatusForUid; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isUidNetworkingBlocked; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isUidRestrictedOnMeteredNetworks; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class NetworkPolicyManagerTest extends AbstractRestrictBackgroundNetworkTestCase { + private static final boolean METERED = true; + private static final boolean NON_METERED = false; + + @Rule + public final MeterednessConfigurationRule mMeterednessConfiguration = + new MeterednessConfigurationRule(); + + @Before + public void setUp() throws Exception { + super.setUp(); + + assumeTrue(canChangeActiveNetworkMeteredness()); + + registerBroadcastReceiver(); + + removeRestrictBackgroundWhitelist(mUid); + removeRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundChangedReceived(0); + + // Initial state + setBatterySaverMode(false); + setRestrictBackground(false); + setRestrictedNetworkingMode(false); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + + setBatterySaverMode(false); + setRestrictBackground(false); + setRestrictedNetworkingMode(false); + unregisterNetworkCallback(); + } + + @Test + public void testIsUidNetworkingBlocked_withUidNotBlocked() throws Exception { + // Refer to NetworkPolicyManagerService#isUidNetworkingBlockedInternal(), this test is to + // test the cases of non-metered network and uid not matched by any rule. + // If mUid is not blocked by data saver mode or power saver mode, no matter the network is + // metered or non-metered, mUid shouldn't be blocked. + assertFalse(isUidNetworkingBlocked(mUid, METERED)); // Match NTWK_ALLOWED_DEFAULT + assertFalse(isUidNetworkingBlocked(mUid, NON_METERED)); // Match NTWK_ALLOWED_NON_METERED + } + + @Test + public void testIsUidNetworkingBlocked_withSystemUid() throws Exception { + // Refer to NetworkPolicyManagerService#isUidNetworkingBlockedInternal(), this test is to + // test the case of uid is system uid. + // SYSTEM_UID will never be blocked. + assertFalse(isUidNetworkingBlocked(SYSTEM_UID, METERED)); // Match NTWK_ALLOWED_SYSTEM + assertFalse(isUidNetworkingBlocked(SYSTEM_UID, NON_METERED)); // Match NTWK_ALLOWED_SYSTEM + try { + setRestrictBackground(true); + setBatterySaverMode(true); + setRestrictedNetworkingMode(true); + assertNetworkingBlockedStatusForUid(SYSTEM_UID, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_SYSTEM + assertFalse( + isUidNetworkingBlocked(SYSTEM_UID, NON_METERED)); // Match NTWK_ALLOWED_SYSTEM + } finally { + setRestrictBackground(false); + setBatterySaverMode(false); + setRestrictedNetworkingMode(false); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_DEFAULT + } + } + + @Test + public void testIsUidNetworkingBlocked_withDataSaverMode() throws Exception { + // Refer to NetworkPolicyManagerService#isUidNetworkingBlockedInternal(), this test is to + // test the cases of non-metered network, uid is matched by restrict background blacklist, + // uid is matched by restrict background whitelist, app is in the foreground with restrict + // background enabled and the app is in the background with restrict background enabled. + try { + // Enable restrict background and mUid will be blocked because it's not in the + // foreground. + setRestrictBackground(true); + assertNetworkingBlockedStatusForUid(mUid, METERED, + true /* expectedResult */); // Match NTWK_BLOCKED_BG_RESTRICT + + // Although restrict background is enabled and mUid is in the background, but mUid will + // not be blocked if network is non-metered. + assertFalse( + isUidNetworkingBlocked(mUid, NON_METERED)); // Match NTWK_ALLOWED_NON_METERED + + // Add mUid into the restrict background blacklist. + addRestrictBackgroundBlacklist(mUid); + assertNetworkingBlockedStatusForUid(mUid, METERED, + true /* expectedResult */); // Match NTWK_BLOCKED_DENYLIST + + // Although mUid is in the restrict background blacklist, but mUid won't be blocked if + // the network is non-metered. + assertFalse( + isUidNetworkingBlocked(mUid, NON_METERED)); // Match NTWK_ALLOWED_NON_METERED + removeRestrictBackgroundBlacklist(mUid); + + // Add mUid into the restrict background whitelist. + addRestrictBackgroundWhitelist(mUid); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_ALLOWLIST + assertFalse( + isUidNetworkingBlocked(mUid, NON_METERED)); // Match NTWK_ALLOWED_NON_METERED + removeRestrictBackgroundWhitelist(mUid); + + // Make TEST_APP2_PKG go to foreground and mUid will be allowed temporarily. + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); + assertForegroundState(); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_TMP_ALLOWLIST + + // Back to background. + finishActivity(); + assertNetworkingBlockedStatusForUid(mUid, METERED, + true /* expectedResult */); // Match NTWK_BLOCKED_BG_RESTRICT + } finally { + setRestrictBackground(false); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_DEFAULT + } + } + + @Test + public void testIsUidNetworkingBlocked_withRestrictedNetworkingMode() throws Exception { + // Refer to NetworkPolicyManagerService#isUidNetworkingBlockedInternal(), this test is to + // test the cases of restricted networking mode enabled. + try { + // All apps should be blocked if restricted networking mode is enabled except for those + // apps who have CONNECTIVITY_USE_RESTRICTED_NETWORKS permission. + // This test won't test if an app who has CONNECTIVITY_USE_RESTRICTED_NETWORKS will not + // be blocked because CONNECTIVITY_USE_RESTRICTED_NETWORKS is a signature/privileged + // permission that CTS cannot acquire. Also it's not good for this test to use those + // privileged apps which have CONNECTIVITY_USE_RESTRICTED_NETWORKS to test because there + // is no guarantee that those apps won't remove this permission someday, and if it + // happens, then this test will fail. + setRestrictedNetworkingMode(true); + assertNetworkingBlockedStatusForUid(mUid, METERED, + true /* expectedResult */); // Match NTWK_BLOCKED_RESTRICTED_MODE + assertTrue(isUidNetworkingBlocked(mUid, + NON_METERED)); // Match NTWK_BLOCKED_RESTRICTED_MODE + } finally { + setRestrictedNetworkingMode(false); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_DEFAULT + } + } + + @Test + public void testIsUidNetworkingBlocked_withPowerSaverMode() throws Exception { + // Refer to NetworkPolicyManagerService#isUidNetworkingBlockedInternal(), this test is to + // test the cases of power saver mode enabled, uid in the power saver mode whitelist and + // uid in the power saver mode whitelist with non-metered network. + try { + // mUid should be blocked if power saver mode is enabled. + setBatterySaverMode(true); + assertNetworkingBlockedStatusForUid(mUid, METERED, + true /* expectedResult */); // Match NTWK_BLOCKED_POWER + assertTrue(isUidNetworkingBlocked(mUid, NON_METERED)); // Match NTWK_BLOCKED_POWER + + // Add TEST_APP2_PKG into power saver mode whitelist, its uid rule is RULE_ALLOW_ALL and + // it shouldn't be blocked. + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_DEFAULT + assertFalse( + isUidNetworkingBlocked(mUid, NON_METERED)); // Match NTWK_ALLOWED_NON_METERED + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } finally { + setBatterySaverMode(false); + assertNetworkingBlockedStatusForUid(mUid, METERED, + false /* expectedResult */); // Match NTWK_ALLOWED_DEFAULT + } + } + + @Test + public void testIsUidRestrictedOnMeteredNetworks() throws Exception { + try { + // isUidRestrictedOnMeteredNetworks() will only return true when restrict background is + // enabled and mUid is not in the restrict background whitelist and TEST_APP2_PKG is not + // in the foreground. For other cases, it will return false. + setRestrictBackground(true); + assertTrue(isUidRestrictedOnMeteredNetworks(mUid)); + + // Make TEST_APP2_PKG go to foreground and isUidRestrictedOnMeteredNetworks() will + // return false. + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); + assertForegroundState(); + assertFalse(isUidRestrictedOnMeteredNetworks(mUid)); + // Back to background. + finishActivity(); + + // Add mUid into restrict background whitelist and isUidRestrictedOnMeteredNetworks() + // will return false. + addRestrictBackgroundWhitelist(mUid); + assertFalse(isUidRestrictedOnMeteredNetworks(mUid)); + removeRestrictBackgroundWhitelist(mUid); + } finally { + // Restrict background is disabled and isUidRestrictedOnMeteredNetworks() will return + // false. + setRestrictBackground(false); + assertFalse(isUidRestrictedOnMeteredNetworks(mUid)); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java index e62d5571ff..05576ccc2f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java @@ -43,6 +43,7 @@ import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkPolicyManager; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.ActionListener; @@ -57,6 +58,7 @@ import androidx.test.platform.app.InstrumentationRegistry; import com.android.compatibility.common.util.AppStandbyUtils; import com.android.compatibility.common.util.BatteryUtils; +import com.android.compatibility.common.util.PollingCheck; import com.android.compatibility.common.util.ShellIdentityUtils; import com.android.compatibility.common.util.ThrowingRunnable; @@ -80,6 +82,7 @@ public class NetworkPolicyTestUtils { private static ConnectivityManager mCm; private static WifiManager mWm; private static CarrierConfigManager mCarrierConfigManager; + private static NetworkPolicyManager sNpm; private static Boolean mBatterySaverSupported; private static Boolean mDataSaverSupported; @@ -401,6 +404,13 @@ public class NetworkPolicyTestUtils { return mCarrierConfigManager; } + public static NetworkPolicyManager getNetworkPolicyManager() { + if (sNpm == null) { + sNpm = getContext().getSystemService(NetworkPolicyManager.class); + } + return sNpm; + } + public static Context getContext() { return getInstrumentation().getContext(); } @@ -408,4 +418,33 @@ public class NetworkPolicyTestUtils { public static Instrumentation getInstrumentation() { return InstrumentationRegistry.getInstrumentation(); } + + // When power saver mode or restrict background enabled or adding any white/black list into + // those modes, NetworkPolicy may need to take some time to update the rules of uids. So having + // this function and using PollingCheck to try to make sure the uid has updated and reduce the + // flaky rate. + public static void assertNetworkingBlockedStatusForUid(int uid, boolean metered, + boolean expectedResult) throws Exception { + PollingCheck.waitFor(() -> (expectedResult == isUidNetworkingBlocked(uid, metered))); + } + + public static boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork) { + final UiAutomation uiAutomation = getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + return getNetworkPolicyManager().isUidNetworkingBlocked(uid, meteredNetwork); + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } + + public static boolean isUidRestrictedOnMeteredNetworks(int uid) { + final UiAutomation uiAutomation = getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + return getNetworkPolicyManager().isUidRestrictedOnMeteredNetworks(uid); + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java index 29d3c6e1ba..5f0f6d6bea 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java @@ -28,28 +28,17 @@ public final class RestrictedModeTest extends AbstractRestrictBackgroundNetworkT @After public void tearDown() throws Exception { - setRestrictedMode(false); + setRestrictedNetworkingMode(false); super.tearDown(); } - private void setRestrictedMode(boolean enabled) throws Exception { - executeSilentShellCommand( - "settings put global restricted_networking_mode " + (enabled ? 1 : 0)); - assertRestrictedModeState(enabled); - } - - private void assertRestrictedModeState(boolean enabled) throws Exception { - assertDelayedShellCommand("cmd netpolicy get restricted-mode", - "Restricted mode status: " + (enabled ? "enabled" : "disabled")); - } - @Test public void testNetworkAccess() throws Exception { - setRestrictedMode(false); + setRestrictedNetworkingMode(false); // go to foreground state and enable restricted mode launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); - setRestrictedMode(true); + setRestrictedNetworkingMode(true); assertForegroundNetworkAccess(false); // go to background state @@ -57,7 +46,7 @@ public final class RestrictedModeTest extends AbstractRestrictBackgroundNetworkT assertBackgroundNetworkAccess(false); // disable restricted mode and assert network access in foreground and background states - setRestrictedMode(false); + setRestrictedNetworkingMode(false); launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); assertForegroundNetworkAccess(true); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkPolicyManagerTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkPolicyManagerTests.java new file mode 100644 index 0000000000..fdb8876a36 --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkPolicyManagerTests.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.cts.net; + +public class HostsideNetworkPolicyManagerTests extends HostsideNetworkTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + uninstallPackage(TEST_APP2_PKG, false); + installPackage(TEST_APP2_APK); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + uninstallPackage(TEST_APP2_PKG, true); + } + + public void testIsUidNetworkingBlocked_withUidNotBlocked() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkPolicyManagerTest", + "testIsUidNetworkingBlocked_withUidNotBlocked"); + } + + public void testIsUidNetworkingBlocked_withSystemUid() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkPolicyManagerTest", "testIsUidNetworkingBlocked_withSystemUid"); + } + + public void testIsUidNetworkingBlocked_withDataSaverMode() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkPolicyManagerTest", + "testIsUidNetworkingBlocked_withDataSaverMode"); + } + + public void testIsUidNetworkingBlocked_withRestrictedNetworkingMode() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkPolicyManagerTest", + "testIsUidNetworkingBlocked_withRestrictedNetworkingMode"); + } + + public void testIsUidNetworkingBlocked_withPowerSaverMode() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkPolicyManagerTest", + "testIsUidNetworkingBlocked_withPowerSaverMode"); + } + + public void testIsUidRestrictedOnMeteredNetworks() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkPolicyManagerTest", "testIsUidRestrictedOnMeteredNetworks"); + } +}