Merge changes from topics "vpnmove-getconnectionowneruid", "vpnmove-systemdefaultcallback", "vpnmove-vpntransportinfo"
* changes: Accept both pre-S and post-S errors in getConnectionOwnerUid. Add CTS coverage for VpnTransportInfo. Add test coverage for registerSystemDefaultNetworkCallback.
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.cts.net.hostside;
|
||||
|
||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
import static android.os.Process.INVALID_UID;
|
||||
import static android.system.OsConstants.AF_INET;
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
@@ -25,6 +27,9 @@ import static android.system.OsConstants.IPPROTO_ICMPV6;
|
||||
import static android.system.OsConstants.IPPROTO_TCP;
|
||||
import static android.system.OsConstants.POLLIN;
|
||||
import static android.system.OsConstants.SOCK_DGRAM;
|
||||
import static android.test.MoreAsserts.assertNotEqual;
|
||||
|
||||
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.DownloadManager;
|
||||
@@ -45,9 +50,14 @@ import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.Proxy;
|
||||
import android.net.ProxyInfo;
|
||||
import android.net.TransportInfo;
|
||||
import android.net.Uri;
|
||||
import android.net.VpnManager;
|
||||
import android.net.VpnService;
|
||||
import android.net.VpnTransportInfo;
|
||||
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;
|
||||
@@ -687,6 +697,20 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
setAndVerifyPrivateDns(initialMode);
|
||||
}
|
||||
|
||||
private class NeverChangeNetworkCallback extends NetworkCallback {
|
||||
private volatile Network mLastNetwork;
|
||||
|
||||
public void onAvailable(Network n) {
|
||||
assertNull("Callback got onAvailable more than once: " + mLastNetwork + ", " + n,
|
||||
mLastNetwork);
|
||||
mLastNetwork = n;
|
||||
}
|
||||
|
||||
public Network getLastNetwork() {
|
||||
return mLastNetwork;
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefault() throws Exception {
|
||||
if (!supportedHardware()) return;
|
||||
// If adb TCP port opened, this test may running by adb over network.
|
||||
@@ -702,6 +726,14 @@ 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();
|
||||
final Network defaultNetwork = mCM.getActiveNetwork();
|
||||
runWithShellPermissionIdentity(() ->
|
||||
mCM.registerSystemDefaultNetworkCallback(neverChangeCallback,
|
||||
new Handler(Looper.getMainLooper())), NETWORK_SETTINGS);
|
||||
|
||||
FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
|
||||
|
||||
startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
|
||||
@@ -719,6 +751,19 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
|
||||
checkTrafficOnVpn();
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
|
||||
// Check that system default network callback has not seen any network changes, but the app
|
||||
// default network callback has. 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 could cause the default network to switch (e.g., from wifi
|
||||
// to cellular).
|
||||
assertEquals(defaultNetwork, neverChangeCallback.getLastNetwork());
|
||||
assertNotEqual(defaultNetwork, mCM.getActiveNetwork());
|
||||
runWithShellPermissionIdentity(
|
||||
() -> mCM.unregisterNetworkCallback(neverChangeCallback),
|
||||
NETWORK_SETTINGS);
|
||||
|
||||
checkStrictModePrivateDns();
|
||||
|
||||
receiver.unregisterQuietly();
|
||||
@@ -739,6 +784,8 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
|
||||
checkTrafficOnVpn();
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
|
||||
checkStrictModePrivateDns();
|
||||
}
|
||||
|
||||
@@ -764,6 +811,10 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
assertSocketStillOpen(remoteFd, TEST_HOST);
|
||||
|
||||
checkNoTrafficOnVpn();
|
||||
|
||||
final Network network = mCM.getActiveNetwork();
|
||||
final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
|
||||
assertFalse(nc.hasTransport(TRANSPORT_VPN));
|
||||
}
|
||||
|
||||
public void testGetConnectionOwnerUidSecurity() throws Exception {
|
||||
@@ -778,8 +829,11 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
|
||||
try {
|
||||
int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem);
|
||||
fail("Only an active VPN app may call this API.");
|
||||
} catch (SecurityException expected) {
|
||||
assertEquals("Only an active VPN app should see connection information",
|
||||
INVALID_UID, uid);
|
||||
} catch (SecurityException acceptable) {
|
||||
// R and below throw SecurityException if a non-active VPN calls this method.
|
||||
// As long as we can't actually get socket information, either behaviour is fine.
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -918,6 +972,8 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
// VPN with no underlying networks should be metered by default.
|
||||
assertTrue(isNetworkMetered(mNetwork));
|
||||
assertTrue(mCM.isActiveNetworkMetered());
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
}
|
||||
|
||||
public void testVpnMeterednessWithNullUnderlyingNetwork() throws Exception {
|
||||
@@ -944,6 +1000,8 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
assertEquals(isNetworkMetered(underlyingNetwork), isNetworkMetered(mNetwork));
|
||||
// Meteredness based on VPN capabilities and CM#isActiveNetworkMetered should be in sync.
|
||||
assertEquals(isNetworkMetered(mNetwork), mCM.isActiveNetworkMetered());
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
}
|
||||
|
||||
public void testVpnMeterednessWithNonNullUnderlyingNetwork() throws Exception {
|
||||
@@ -971,6 +1029,8 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
assertEquals(isNetworkMetered(underlyingNetwork), isNetworkMetered(mNetwork));
|
||||
// Meteredness based on VPN capabilities and CM#isActiveNetworkMetered should be in sync.
|
||||
assertEquals(isNetworkMetered(mNetwork), mCM.isActiveNetworkMetered());
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
}
|
||||
|
||||
public void testAlwaysMeteredVpnWithNullUnderlyingNetwork() throws Exception {
|
||||
@@ -995,6 +1055,8 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
// VPN's meteredness does not depend on underlying network since it is always metered.
|
||||
assertTrue(isNetworkMetered(mNetwork));
|
||||
assertTrue(mCM.isActiveNetworkMetered());
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
}
|
||||
|
||||
public void testAlwaysMeteredVpnWithNonNullUnderlyingNetwork() throws Exception {
|
||||
@@ -1020,6 +1082,8 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
// VPN's meteredness does not depend on underlying network since it is always metered.
|
||||
assertTrue(isNetworkMetered(mNetwork));
|
||||
assertTrue(mCM.isActiveNetworkMetered());
|
||||
|
||||
expectVpnTransportInfo(mCM.getActiveNetwork());
|
||||
}
|
||||
|
||||
public void testB141603906() throws Exception {
|
||||
@@ -1069,6 +1133,14 @@ public class VpnTest extends InstrumentationTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private void expectVpnTransportInfo(Network network) {
|
||||
final NetworkCapabilities vpnNc = mCM.getNetworkCapabilities(network);
|
||||
assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
|
||||
final TransportInfo ti = vpnNc.getTransportInfo();
|
||||
assertTrue(ti instanceof VpnTransportInfo);
|
||||
assertEquals(VpnManager.TYPE_VPN_SERVICE, ((VpnTransportInfo) ti).type);
|
||||
}
|
||||
|
||||
private void assertDefaultProxy(ProxyInfo expected) {
|
||||
assertEquals("Incorrect proxy config.", expected, mCM.getDefaultProxy());
|
||||
String expectedHost = expected == null ? null : expected.getHost();
|
||||
|
||||
@@ -93,6 +93,7 @@ import android.net.util.KeepaliveUtils;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.os.SystemClock;
|
||||
@@ -532,6 +533,13 @@ public class ConnectivityManagerTest {
|
||||
final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
|
||||
mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
|
||||
|
||||
final TestNetworkCallback systemDefaultTrackingCallback = new TestNetworkCallback();
|
||||
runWithShellPermissionIdentity(() ->
|
||||
mCm.registerSystemDefaultNetworkCallback(systemDefaultTrackingCallback,
|
||||
new Handler(Looper.getMainLooper())),
|
||||
NETWORK_SETTINGS);
|
||||
|
||||
|
||||
Network wifiNetwork = null;
|
||||
|
||||
try {
|
||||
@@ -551,6 +559,9 @@ public class ConnectivityManagerTest {
|
||||
} finally {
|
||||
mCm.unregisterNetworkCallback(callback);
|
||||
mCm.unregisterNetworkCallback(defaultTrackingCallback);
|
||||
runWithShellPermissionIdentity(
|
||||
() -> mCm.unregisterNetworkCallback(systemDefaultTrackingCallback),
|
||||
NETWORK_SETTINGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ import android.net.RouteInfo
|
||||
import android.net.SocketKeepalive
|
||||
import android.net.StringNetworkSpecifier
|
||||
import android.net.Uri
|
||||
import android.net.VpnManager
|
||||
import android.net.VpnTransportInfo
|
||||
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter
|
||||
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled
|
||||
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested
|
||||
@@ -545,7 +547,7 @@ class NetworkAgentTest {
|
||||
|
||||
@Test
|
||||
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||
fun testSetUnderlyingNetworks() {
|
||||
fun testSetUnderlyingNetworksAndVpnSpecifier() {
|
||||
val request = NetworkRequest.Builder()
|
||||
.addTransportType(TRANSPORT_TEST)
|
||||
.addTransportType(TRANSPORT_VPN)
|
||||
@@ -560,6 +562,7 @@ class NetworkAgentTest {
|
||||
addTransportType(TRANSPORT_VPN)
|
||||
removeCapability(NET_CAPABILITY_NOT_VPN)
|
||||
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||
setTransportInfo(VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE))
|
||||
}
|
||||
val defaultNetwork = mCM.activeNetwork
|
||||
assertNotNull(defaultNetwork)
|
||||
@@ -574,6 +577,8 @@ class NetworkAgentTest {
|
||||
// Check that the default network's transport is propagated to the VPN.
|
||||
var vpnNc = mCM.getNetworkCapabilities(agent.network)
|
||||
assertNotNull(vpnNc)
|
||||
assertEquals(VpnManager.TYPE_VPN_SERVICE,
|
||||
(vpnNc.transportInfo as VpnTransportInfo).type)
|
||||
|
||||
val testAndVpn = intArrayOf(TRANSPORT_TEST, TRANSPORT_VPN)
|
||||
assertTrue(hasAllTransports(vpnNc, testAndVpn))
|
||||
|
||||
Reference in New Issue
Block a user