Merge changes from topic "peruidcallback-cts"

* changes:
  Cleanups to VPN hostside tests.
  Ensure the HostsideVpnTests passes with keyguard locked.
  Add CTS tests for registerDefaultNetworkCallbackAsUid.
This commit is contained in:
Lorenzo Colitti
2021-04-09 15:16:47 +00:00
committed by Gerrit Code Review
4 changed files with 59 additions and 54 deletions

View File

@@ -27,6 +27,7 @@ android_test_helper_app {
"androidx.test.rules", "androidx.test.rules",
"androidx.test.ext.junit", "androidx.test.ext.junit",
"compatibility-device-util-axt", "compatibility-device-util-axt",
"cts-net-utils",
"ctstestrunner-axt", "ctstestrunner-axt",
"ub-uiautomator", "ub-uiautomator",
"CtsHostsideNetworkTestsAidl", "CtsHostsideNetworkTestsAidl",

View File

@@ -17,6 +17,7 @@
package com.android.cts.net.hostside; package com.android.cts.net.hostside;
import android.app.Activity; import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.WindowManager; import android.view.WindowManager;
@@ -34,6 +35,11 @@ public class MyActivity extends Activity {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
// Dismiss the keyguard so that the tests can click on the VPN confirmation dialog.
// FLAG_DISMISS_KEYGUARD is not sufficient to do this because as soon as the dialog appears,
// this activity goes into the background and the keyguard reappears.
getSystemService(KeyguardManager.class).requestDismissKeyguard(this, null /* callback */);
} }
@Override @Override

View File

@@ -61,6 +61,7 @@ import android.os.Looper;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Process; import android.os.Process;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObject;
@@ -76,6 +77,7 @@ import android.util.Log;
import com.android.compatibility.common.util.BlockingBroadcastReceiver; import com.android.compatibility.common.util.BlockingBroadcastReceiver;
import com.android.modules.utils.build.SdkLevel; import com.android.modules.utils.build.SdkLevel;
import com.android.testutils.TestableNetworkCallback;
import java.io.Closeable; import java.io.Closeable;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@@ -92,6 +94,7 @@ import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -698,34 +701,6 @@ public class VpnTest extends InstrumentationTestCase {
setAndVerifyPrivateDns(initialMode); setAndVerifyPrivateDns(initialMode);
} }
private class NeverChangeNetworkCallback extends NetworkCallback {
private CountDownLatch mLatch = new CountDownLatch(1);
private volatile Network mFirstNetwork;
private volatile Network mOtherNetwork;
public void onAvailable(Network n) {
// Don't assert here, as it crashes the test with a hard to debug message.
if (mFirstNetwork == null) {
mFirstNetwork = n;
mLatch.countDown();
} else if (mOtherNetwork == null) {
mOtherNetwork = n;
}
}
public Network getFirstNetwork() throws Exception {
assertTrue(
"System default callback got no network after " + TIMEOUT_MS + "ms. "
+ "Please ensure the device has a working Internet connection.",
mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
return mFirstNetwork;
}
public void assertNeverChanged() {
assertNull(mOtherNetwork);
}
}
public void testDefault() throws Exception { public void testDefault() throws Exception {
if (!supportedHardware()) return; if (!supportedHardware()) return;
// If adb TCP port opened, this test may running by adb over network. // If adb TCP port opened, this test may running by adb over network.
@@ -741,13 +716,24 @@ public class VpnTest extends InstrumentationTestCase {
getInstrumentation().getTargetContext(), MyVpnService.ACTION_ESTABLISHED); getInstrumentation().getTargetContext(), MyVpnService.ACTION_ESTABLISHED);
receiver.register(); receiver.register();
// Expect the system default network not to change. // Test the behaviour of a variety of types of network callbacks.
final NeverChangeNetworkCallback neverChangeCallback = new NeverChangeNetworkCallback();
final Network defaultNetwork = mCM.getActiveNetwork(); final Network defaultNetwork = mCM.getActiveNetwork();
final TestableNetworkCallback systemDefaultCallback = new TestableNetworkCallback();
final TestableNetworkCallback otherUidCallback = new TestableNetworkCallback();
final TestableNetworkCallback myUidCallback = new TestableNetworkCallback();
if (SdkLevel.isAtLeastS()) { if (SdkLevel.isAtLeastS()) {
runWithShellPermissionIdentity(() -> final int otherUid = UserHandle.getUid(UserHandle.of(5), Process.FIRST_APPLICATION_UID);
mCM.registerSystemDefaultNetworkCallback(neverChangeCallback, final Handler h = new Handler(Looper.getMainLooper());
new Handler(Looper.getMainLooper())), NETWORK_SETTINGS); runWithShellPermissionIdentity(() -> {
mCM.registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
mCM.registerDefaultNetworkCallbackAsUid(otherUid, otherUidCallback, h);
mCM.registerDefaultNetworkCallbackAsUid(Process.myUid(), myUidCallback, h);
}, NETWORK_SETTINGS);
for (TestableNetworkCallback callback :
List.of(systemDefaultCallback, otherUidCallback, myUidCallback)) {
callback.expectAvailableCallbacks(defaultNetwork, false /* suspended */,
true /* validated */, false /* blocked */, TIMEOUT_MS);
}
} }
FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
@@ -767,20 +753,24 @@ public class VpnTest extends InstrumentationTestCase {
checkTrafficOnVpn(); checkTrafficOnVpn();
maybeExpectVpnTransportInfo(mCM.getActiveNetwork()); final Network vpnNetwork = mCM.getActiveNetwork();
myUidCallback.expectAvailableThenValidatedCallbacks(vpnNetwork, TIMEOUT_MS);
assertEquals(vpnNetwork, mCM.getActiveNetwork());
assertNotEqual(defaultNetwork, vpnNetwork);
maybeExpectVpnTransportInfo(vpnNetwork);
assertNotEqual(defaultNetwork, mCM.getActiveNetwork());
if (SdkLevel.isAtLeastS()) { if (SdkLevel.isAtLeastS()) {
// Check that system default network callback has not seen any network changes, even // 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 // though the app's default network changed. Also check that otherUidCallback saw no
// private DNS because checkStrictModePrivateDns will set the private DNS server to // network changes, because otherUid is in a different user and not subject to the VPN.
// a nonexistent name, which will cause validation to fail and cause the default // This needs to be done before testing private DNS because checkStrictModePrivateDns
// network to switch (e.g., from wifi to cellular). // will set the private DNS server to a nonexistent name, which will cause validation to
assertEquals(defaultNetwork, neverChangeCallback.getFirstNetwork()); // fail and could cause the default network to switch (e.g., from wifi to cellular).
neverChangeCallback.assertNeverChanged(); systemDefaultCallback.assertNoCallback();
runWithShellPermissionIdentity( otherUidCallback.assertNoCallback();
() -> mCM.unregisterNetworkCallback(neverChangeCallback), mCM.unregisterNetworkCallback(systemDefaultCallback);
NETWORK_SETTINGS); mCM.unregisterNetworkCallback(otherUidCallback);
mCM.unregisterNetworkCallback(myUidCallback);
} }
checkStrictModePrivateDns(); checkStrictModePrivateDns();

View File

@@ -111,6 +111,7 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.MessageQueue; import android.os.MessageQueue;
import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.VintfRuntimeInfo; import android.os.VintfRuntimeInfo;
@@ -587,12 +588,14 @@ public class ConnectivityManagerTest {
final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback(); final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultTrackingCallback); 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()) { if (shouldTestSApis()) {
runWithShellPermissionIdentity(() -> runWithShellPermissionIdentity(() -> {
mCmShim.registerSystemDefaultNetworkCallback(systemDefaultTrackingCallback, mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
new Handler(Looper.getMainLooper())), mCmShim.registerDefaultNetworkCallbackAsUid(Process.myUid(), perUidCallback, h);
NETWORK_SETTINGS); }, NETWORK_SETTINGS);
} }
Network wifiNetwork = null; Network wifiNetwork = null;
@@ -607,22 +610,27 @@ public class ConnectivityManagerTest {
assertNotNull("Did not receive onAvailable for TRANSPORT_WIFI request", assertNotNull("Did not receive onAvailable for TRANSPORT_WIFI request",
wifiNetwork); wifiNetwork);
final Network defaultNetwork = defaultTrackingCallback.waitForAvailable();
assertNotNull("Did not receive onAvailable on default network callback", assertNotNull("Did not receive onAvailable on default network callback",
defaultTrackingCallback.waitForAvailable()); defaultNetwork);
if (shouldTestSApis()) { if (shouldTestSApis()) {
assertNotNull("Did not receive onAvailable on system default network callback", 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) { } catch (InterruptedException e) {
fail("Broadcast receiver or NetworkCallback wait was interrupted."); fail("Broadcast receiver or NetworkCallback wait was interrupted.");
} finally { } finally {
mCm.unregisterNetworkCallback(callback); mCm.unregisterNetworkCallback(callback);
mCm.unregisterNetworkCallback(defaultTrackingCallback); mCm.unregisterNetworkCallback(defaultTrackingCallback);
if (shouldTestSApis()) { if (shouldTestSApis()) {
runWithShellPermissionIdentity( mCm.unregisterNetworkCallback(systemDefaultCallback);
() -> mCm.unregisterNetworkCallback(systemDefaultTrackingCallback), mCm.unregisterNetworkCallback(perUidCallback);
NETWORK_SETTINGS);
} }
} }
} }