diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp index f351b47fad..112b9eb778 100644 --- a/tests/cts/hostside/app/Android.bp +++ b/tests/cts/hostside/app/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "androidx.test.rules", "androidx.test.ext.junit", "compatibility-device-util-axt", + "cts-net-utils", "ctstestrunner-axt", "ub-uiautomator", "CtsHostsideNetworkTestsAidl", diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 9b437e64a8..a47d3042ae 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -55,12 +55,14 @@ import android.net.Uri; import android.net.VpnManager; import android.net.VpnService; import android.net.VpnTransportInfo; +import android.net.cts.util.CtsNetUtils.TestNetworkCallback; import android.net.wifi.WifiManager; import android.os.Handler; import android.os.Looper; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.SystemProperties; +import android.os.UserHandle; import android.provider.Settings; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; @@ -741,13 +743,20 @@ public class VpnTest extends InstrumentationTestCase { getInstrumentation().getTargetContext(), MyVpnService.ACTION_ESTABLISHED); receiver.register(); - // Expect the system default network not to change. - final NeverChangeNetworkCallback neverChangeCallback = new NeverChangeNetworkCallback(); + // Test the behaviour of a variety of types of network callbacks. final Network defaultNetwork = mCM.getActiveNetwork(); + final NeverChangeNetworkCallback systemDefaultCallback = new NeverChangeNetworkCallback(); + final NeverChangeNetworkCallback otherUidCallback = new NeverChangeNetworkCallback(); + final TestNetworkCallback myUidCallback = new TestNetworkCallback(); if (SdkLevel.isAtLeastS()) { - runWithShellPermissionIdentity(() -> - mCM.registerSystemDefaultNetworkCallback(neverChangeCallback, - new Handler(Looper.getMainLooper())), NETWORK_SETTINGS); + final int otherUid = UserHandle.getUid(UserHandle.of(5), Process.FIRST_APPLICATION_UID); + final Handler h = new Handler(Looper.getMainLooper()); + runWithShellPermissionIdentity(() -> { + mCM.registerSystemDefaultNetworkCallback(systemDefaultCallback, h); + mCM.registerDefaultNetworkCallbackAsUid(otherUid, otherUidCallback, h); + mCM.registerDefaultNetworkCallbackAsUid(Process.myUid(), myUidCallback, h); + }, NETWORK_SETTINGS); + assertEquals(defaultNetwork, myUidCallback.waitForAvailable()); } FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); @@ -767,20 +776,27 @@ public class VpnTest extends InstrumentationTestCase { checkTrafficOnVpn(); - maybeExpectVpnTransportInfo(mCM.getActiveNetwork()); + final Network vpnNetwork = myUidCallback.waitForAvailable(); + assertEquals(vpnNetwork, mCM.getActiveNetwork()); + assertNotEqual(defaultNetwork, vpnNetwork); + maybeExpectVpnTransportInfo(vpnNetwork); - assertNotEqual(defaultNetwork, mCM.getActiveNetwork()); if (SdkLevel.isAtLeastS()) { // Check that system default network callback has not seen any network changes, even - // though the app's default network changed. This needs to be done before testing - // private DNS because checkStrictModePrivateDns will set the private DNS server to - // a nonexistent name, which will cause validation to fail and cause the default - // network to switch (e.g., from wifi to cellular). - assertEquals(defaultNetwork, neverChangeCallback.getFirstNetwork()); - neverChangeCallback.assertNeverChanged(); - runWithShellPermissionIdentity( - () -> mCM.unregisterNetworkCallback(neverChangeCallback), - NETWORK_SETTINGS); + // though the app's default network changed. Also check that otherUidCallback saw no + // network changes, because otherUid is in a different user and not subject to the VPN. + // This needs to be done before testing private DNS because checkStrictModePrivateDns + // will set the private DNS server to a nonexistent name, which will cause validation to + // fail and could cause the default network to switch (e.g., from wifi to cellular). + assertEquals(defaultNetwork, systemDefaultCallback.getFirstNetwork()); + systemDefaultCallback.assertNeverChanged(); + assertEquals(defaultNetwork, otherUidCallback.getFirstNetwork()); + otherUidCallback.assertNeverChanged(); + runWithShellPermissionIdentity(() -> { + mCM.unregisterNetworkCallback(systemDefaultCallback); + mCM.unregisterNetworkCallback(otherUidCallback); + mCM.unregisterNetworkCallback(myUidCallback); + }, NETWORK_SETTINGS); } checkStrictModePrivateDns(); diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 096f656eaf..18f05888b4 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -111,6 +111,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; +import android.os.Process; import android.os.SystemClock; import android.os.SystemProperties; import android.os.VintfRuntimeInfo; @@ -587,12 +588,14 @@ public class ConnectivityManagerTest { final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback(); mCm.registerDefaultNetworkCallback(defaultTrackingCallback); - final TestNetworkCallback systemDefaultTrackingCallback = new TestNetworkCallback(); + final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); + final TestNetworkCallback perUidCallback = new TestNetworkCallback(); + final Handler h = new Handler(Looper.getMainLooper()); if (shouldTestSApis()) { - runWithShellPermissionIdentity(() -> - mCmShim.registerSystemDefaultNetworkCallback(systemDefaultTrackingCallback, - new Handler(Looper.getMainLooper())), - NETWORK_SETTINGS); + runWithShellPermissionIdentity(() -> { + mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback, h); + mCmShim.registerDefaultNetworkCallbackAsUid(Process.myUid(), perUidCallback, h); + }, NETWORK_SETTINGS); } Network wifiNetwork = null; @@ -607,22 +610,27 @@ public class ConnectivityManagerTest { assertNotNull("Did not receive onAvailable for TRANSPORT_WIFI request", wifiNetwork); + final Network defaultNetwork = defaultTrackingCallback.waitForAvailable(); assertNotNull("Did not receive onAvailable on default network callback", - defaultTrackingCallback.waitForAvailable()); + defaultNetwork); if (shouldTestSApis()) { assertNotNull("Did not receive onAvailable on system default network callback", - systemDefaultTrackingCallback.waitForAvailable()); + systemDefaultCallback.waitForAvailable()); + final Network perUidNetwork = perUidCallback.waitForAvailable(); + assertNotNull("Did not receive onAvailable on per-UID default network callback", + perUidNetwork); + assertEquals(defaultNetwork, perUidNetwork); } + } catch (InterruptedException e) { fail("Broadcast receiver or NetworkCallback wait was interrupted."); } finally { mCm.unregisterNetworkCallback(callback); mCm.unregisterNetworkCallback(defaultTrackingCallback); if (shouldTestSApis()) { - runWithShellPermissionIdentity( - () -> mCm.unregisterNetworkCallback(systemDefaultTrackingCallback), - NETWORK_SETTINGS); + mCm.unregisterNetworkCallback(systemDefaultCallback); + mCm.unregisterNetworkCallback(perUidCallback); } } }