Merge changes Id4632e1b,I31985822,Ibbf96a25
* changes: Test passing an underlying network array with null network in it. Make testVpnNetworkActive more deterministic. Add a test for restricted profile added/removed with VPN up.
This commit is contained in:
@@ -18,6 +18,8 @@ package com.android.server;
|
||||
|
||||
import static android.Manifest.permission.CHANGE_NETWORK_STATE;
|
||||
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
||||
import static android.content.Intent.ACTION_USER_ADDED;
|
||||
import static android.content.Intent.ACTION_USER_REMOVED;
|
||||
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
|
||||
import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
||||
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
||||
@@ -4944,8 +4946,6 @@ public class ConnectivityServiceTest {
|
||||
|
||||
final Network[] cellAndVpn = new Network[] {
|
||||
mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
|
||||
Network[] cellAndWifi = new Network[] {
|
||||
mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()};
|
||||
|
||||
// A VPN with default (null) underlying networks sets the underlying network's interfaces...
|
||||
expectForceUpdateIfaces(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
@@ -4955,10 +4955,13 @@ public class ConnectivityServiceTest {
|
||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||
mWiFiNetworkAgent.connect(false);
|
||||
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
|
||||
final Network[] onlyNull = new Network[]{null};
|
||||
final Network[] wifiAndVpn = new Network[] {
|
||||
mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
|
||||
cellAndWifi = new Network[] {
|
||||
final Network[] cellAndWifi = new Network[] {
|
||||
mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()};
|
||||
final Network[] cellNullAndWifi = new Network[] {
|
||||
mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()};
|
||||
|
||||
waitForIdle();
|
||||
assertEquals(wifiLp, mService.getActiveLinkProperties());
|
||||
@@ -4984,6 +4987,13 @@ public class ConnectivityServiceTest {
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
|
||||
// Null underlying networks are ignored.
|
||||
mService.setUnderlyingNetworksForVpn(cellNullAndWifi);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
|
||||
// If an underlying network disconnects, that interface should no longer be underlying.
|
||||
// This doesn't actually work because disconnectAndDestroyNetwork only notifies
|
||||
// NetworkStatsService before the underlying network is actually removed. So the underlying
|
||||
@@ -5018,6 +5028,7 @@ public class ConnectivityServiceTest {
|
||||
argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.length == 1
|
||||
&& WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces[0])));
|
||||
mEthernetNetworkAgent.disconnect();
|
||||
waitForIdle();
|
||||
reset(mStatsService);
|
||||
|
||||
// When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo
|
||||
@@ -5030,6 +5041,18 @@ public class ConnectivityServiceTest {
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
|
||||
// Specifying only a null underlying network is the same as no networks.
|
||||
mService.setUnderlyingNetworksForVpn(onlyNull);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
|
||||
// Specifying networks that are all disconnected is the same as specifying no networks.
|
||||
mService.setUnderlyingNetworksForVpn(onlyCell);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -5471,6 +5494,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
final Set<UidRange> ranges = uidRangesForUid(uid);
|
||||
mMockVpn.registerAgent(ranges);
|
||||
mService.setUnderlyingNetworksForVpn(new Network[0]);
|
||||
|
||||
// VPN networks do not satisfy the default request and are automatically validated
|
||||
// by NetworkMonitor
|
||||
@@ -5479,19 +5503,12 @@ public class ConnectivityServiceTest {
|
||||
mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */);
|
||||
|
||||
mMockVpn.connect(false);
|
||||
mService.setUnderlyingNetworksForVpn(new Network[0]);
|
||||
|
||||
genericNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
|
||||
genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
genericNotVpnNetworkCallback.assertNoCallback();
|
||||
wifiNetworkCallback.assertNoCallback();
|
||||
vpnNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
|
||||
defaultCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
|
||||
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||
|
||||
genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
|
||||
genericNotVpnNetworkCallback.assertNoCallback();
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, nc -> null == nc.getUids());
|
||||
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
|
||||
vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
|
||||
|
||||
ranges.clear();
|
||||
@@ -5883,6 +5900,75 @@ public class ConnectivityServiceTest {
|
||||
mMockVpn.disconnect();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVpnRestrictedUsers() throws Exception {
|
||||
// NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities.
|
||||
mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
|
||||
PERMISSION_GRANTED);
|
||||
|
||||
final NetworkRequest request = new NetworkRequest.Builder()
|
||||
.removeCapability(NET_CAPABILITY_NOT_VPN)
|
||||
.build();
|
||||
final TestNetworkCallback callback = new TestNetworkCallback();
|
||||
mCm.registerNetworkCallback(request, callback);
|
||||
|
||||
// Bring up a VPN
|
||||
mMockVpn.establishForMyUid();
|
||||
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
callback.assertNoCallback();
|
||||
|
||||
final int uid = Process.myUid();
|
||||
NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
|
||||
assertNotNull("nc=" + nc, nc.getUids());
|
||||
assertEquals(nc.getUids(), uidRangesForUid(uid));
|
||||
|
||||
// Set an underlying network and expect to see the VPN transports change.
|
||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||
mWiFiNetworkAgent.connect(true);
|
||||
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
||||
-> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_WIFI));
|
||||
callback.expectCapabilitiesThat(mWiFiNetworkAgent, (caps)
|
||||
-> caps.hasCapability(NET_CAPABILITY_VALIDATED));
|
||||
|
||||
// Create a fake restricted profile whose parent is our user ID.
|
||||
final int userId = UserHandle.getUserId(uid);
|
||||
final int restrictedUserId = userId + 1;
|
||||
final UserInfo info = new UserInfo(restrictedUserId, "user", UserInfo.FLAG_RESTRICTED);
|
||||
info.restrictedProfileParentId = userId;
|
||||
assertTrue(info.isRestricted());
|
||||
when(mUserManager.getUserInfo(restrictedUserId)).thenReturn(info);
|
||||
final Intent addedIntent = new Intent(ACTION_USER_ADDED);
|
||||
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId);
|
||||
|
||||
// Send a USER_ADDED broadcast for it.
|
||||
// The BroadcastReceiver for this broadcast checks that is being run on the handler thread.
|
||||
final Handler handler = new Handler(mCsHandlerThread.getLooper());
|
||||
handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
|
||||
|
||||
// Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
|
||||
// restricted user.
|
||||
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
||||
-> caps.getUids().size() == 2
|
||||
&& caps.getUids().contains(new UidRange(uid, uid))
|
||||
&& caps.getUids().contains(UidRange.createForUser(restrictedUserId))
|
||||
&& caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_WIFI));
|
||||
|
||||
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
|
||||
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
|
||||
removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId);
|
||||
handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
|
||||
|
||||
// Expect that the VPN gains the UID range for the restricted user.
|
||||
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
||||
-> caps.getUids().size() == 1
|
||||
&& caps.getUids().contains(new UidRange(uid, uid))
|
||||
&& caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_WIFI));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsActiveNetworkMeteredOverWifi() throws Exception {
|
||||
// Returns true by default when no network is available.
|
||||
|
||||
Reference in New Issue
Block a user