14d03abcd49af490dba3850d341b955dd72f24959Robin Lee/* 24d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Copyright (C) 2016 The Android Open Source Project 34d03abcd49af490dba3850d341b955dd72f24959Robin Lee * 44d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Licensed under the Apache License, Version 2.0 (the "License"); 54d03abcd49af490dba3850d341b955dd72f24959Robin Lee * you may not use this file except in compliance with the License. 64d03abcd49af490dba3850d341b955dd72f24959Robin Lee * You may obtain a copy of the License at 74d03abcd49af490dba3850d341b955dd72f24959Robin Lee * 84d03abcd49af490dba3850d341b955dd72f24959Robin Lee * http://www.apache.org/licenses/LICENSE-2.0 94d03abcd49af490dba3850d341b955dd72f24959Robin Lee * 104d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Unless required by applicable law or agreed to in writing, software 114d03abcd49af490dba3850d341b955dd72f24959Robin Lee * distributed under the License is distributed on an "AS IS" BASIS, 124d03abcd49af490dba3850d341b955dd72f24959Robin Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d03abcd49af490dba3850d341b955dd72f24959Robin Lee * See the License for the specific language governing permissions and 144d03abcd49af490dba3850d341b955dd72f24959Robin Lee * limitations under the License. 154d03abcd49af490dba3850d341b955dd72f24959Robin Lee */ 164d03abcd49af490dba3850d341b955dd72f24959Robin Lee 174d03abcd49af490dba3850d341b955dd72f24959Robin Leepackage com.android.server.connectivity; 184d03abcd49af490dba3850d341b955dd72f24959Robin Lee 194d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport static android.content.pm.UserInfo.FLAG_ADMIN; 204d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; 214d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport static android.content.pm.UserInfo.FLAG_PRIMARY; 224d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport static android.content.pm.UserInfo.FLAG_RESTRICTED; 2372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; 2472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 259b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkeyimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 2672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 2772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; 2872f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 2972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.TRANSPORT_VPN; 3072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static android.net.NetworkCapabilities.TRANSPORT_WIFI; 3172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 324a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichiimport static org.junit.Assert.assertEquals; 334a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichiimport static org.junit.Assert.assertFalse; 344a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichiimport static org.junit.Assert.assertTrue; 3572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.AdditionalMatchers.aryEq; 3672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.ArgumentMatchers.any; 3772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.ArgumentMatchers.anyBoolean; 3872f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.ArgumentMatchers.anyInt; 3972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.ArgumentMatchers.anyString; 4072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.ArgumentMatchers.eq; 4172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.atLeastOnce; 4272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.doAnswer; 4372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.doNothing; 4472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.inOrder; 4572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.times; 4672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.verify; 4772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport static org.mockito.Mockito.when; 484d03abcd49af490dba3850d341b955dd72f24959Robin Lee 494d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.annotation.UserIdInt; 5017e6183b85ba3038acb935aaa01415058b2e6dddRobin Leeimport android.app.AppOpsManager; 51de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Makimport android.app.NotificationManager; 524d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.content.Context; 53b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Leeimport android.content.pm.ApplicationInfo; 544d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.content.pm.PackageManager; 55a0a87e810870b696239f0371d33de924f84cb431Charles Heimport android.content.pm.ResolveInfo; 56a0a87e810870b696239f0371d33de924f84cb431Charles Heimport android.content.pm.ServiceInfo; 574d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.content.pm.UserInfo; 58c17f50f83d3e35f338095df6065426f2f304a1dcCharles Heimport android.content.res.Resources; 5972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport android.net.ConnectivityManager; 60adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jeanimport android.net.IConnectivityManager; 61adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jeanimport android.net.IpPrefix; 62adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jeanimport android.net.LinkProperties; 6372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport android.net.Network; 6472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport android.net.NetworkCapabilities; 65de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Makimport android.net.NetworkInfo.DetailedState; 66adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jeanimport android.net.RouteInfo; 674d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.net.UidRange; 68a0a87e810870b696239f0371d33de924f84cb431Charles Heimport android.net.VpnService; 69a0a87e810870b696239f0371d33de924f84cb431Charles Heimport android.os.Build.VERSION_CODES; 70a0a87e810870b696239f0371d33de924f84cb431Charles Heimport android.os.Bundle; 714d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.os.INetworkManagementService; 724d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.os.Looper; 73507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jeanimport android.os.SystemClock; 744d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.os.UserHandle; 754d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.os.UserManager; 764a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichiimport android.support.test.filters.SmallTest; 7772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport android.support.test.runner.AndroidJUnit4; 784d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.util.ArrayMap; 794d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport android.util.ArraySet; 804d03abcd49af490dba3850d341b955dd72f24959Robin Lee 81c17f50f83d3e35f338095df6065426f2f304a1dcCharles Heimport com.android.internal.R; 82c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Leeimport com.android.internal.net.VpnConfig; 83c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 844a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichiimport org.junit.Before; 854a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichiimport org.junit.Test; 8672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport org.junit.runner.RunWith; 87b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Leeimport org.mockito.Answers; 88de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Makimport org.mockito.InOrder; 894d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport org.mockito.Mock; 904d03abcd49af490dba3850d341b955dd72f24959Robin Leeimport org.mockito.MockitoAnnotations; 914d03abcd49af490dba3850d341b955dd72f24959Robin Lee 92507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jeanimport java.net.Inet4Address; 93507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jeanimport java.net.UnknownHostException; 94a0a87e810870b696239f0371d33de924f84cb431Charles Heimport java.util.ArrayList; 95a0a87e810870b696239f0371d33de924f84cb431Charles Heimport java.util.Arrays; 96a0a87e810870b696239f0371d33de924f84cb431Charles Heimport java.util.Collections; 9772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkeyimport java.util.HashMap; 98a0a87e810870b696239f0371d33de924f84cb431Charles Heimport java.util.Map; 99a0a87e810870b696239f0371d33de924f84cb431Charles Heimport java.util.Set; 100adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jeanimport java.util.stream.Collectors; 101adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jeanimport java.util.stream.Stream; 1024a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi 1034d03abcd49af490dba3850d341b955dd72f24959Robin Lee/** 1044d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Tests for {@link Vpn}. 1054d03abcd49af490dba3850d341b955dd72f24959Robin Lee * 1064d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Build, install and run with: 1074a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi * runtest frameworks-net -c com.android.server.connectivity.VpnTest 1084d03abcd49af490dba3850d341b955dd72f24959Robin Lee */ 1094a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi@RunWith(AndroidJUnit4.class) 1104a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi@SmallTest 1114a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichipublic class VpnTest { 1124d03abcd49af490dba3850d341b955dd72f24959Robin Lee private static final String TAG = "VpnTest"; 1134d03abcd49af490dba3850d341b955dd72f24959Robin Lee 1144d03abcd49af490dba3850d341b955dd72f24959Robin Lee // Mock users 1154d03abcd49af490dba3850d341b955dd72f24959Robin Lee static final UserInfo primaryUser = new UserInfo(27, "Primary", FLAG_ADMIN | FLAG_PRIMARY); 1164d03abcd49af490dba3850d341b955dd72f24959Robin Lee static final UserInfo secondaryUser = new UserInfo(15, "Secondary", FLAG_ADMIN); 1174d03abcd49af490dba3850d341b955dd72f24959Robin Lee static final UserInfo restrictedProfileA = new UserInfo(40, "RestrictedA", FLAG_RESTRICTED); 1184d03abcd49af490dba3850d341b955dd72f24959Robin Lee static final UserInfo restrictedProfileB = new UserInfo(42, "RestrictedB", FLAG_RESTRICTED); 1194d03abcd49af490dba3850d341b955dd72f24959Robin Lee static final UserInfo managedProfileA = new UserInfo(45, "ManagedA", FLAG_MANAGED_PROFILE); 1204d03abcd49af490dba3850d341b955dd72f24959Robin Lee static { 1214d03abcd49af490dba3850d341b955dd72f24959Robin Lee restrictedProfileA.restrictedProfileParentId = primaryUser.id; 1224d03abcd49af490dba3850d341b955dd72f24959Robin Lee restrictedProfileB.restrictedProfileParentId = secondaryUser.id; 1234d03abcd49af490dba3850d341b955dd72f24959Robin Lee managedProfileA.profileGroupId = primaryUser.id; 1244d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 1254d03abcd49af490dba3850d341b955dd72f24959Robin Lee 12617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee /** 12717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee * Names and UIDs for some fake packages. Important points: 12817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee * - UID is ordered increasing. 12917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee * - One pair of packages have consecutive UIDs. 13017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee */ 13117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee static final String[] PKGS = {"com.example", "org.example", "net.example", "web.vpn"}; 13217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee static final int[] PKG_UIDS = {66, 77, 78, 400}; 13317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 13417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Mock packages 13517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee static final Map<String, Integer> mPackages = new ArrayMap<>(); 13617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee static { 13717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee for (int i = 0; i < PKGS.length; i++) { 13817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee mPackages.put(PKGS[i], PKG_UIDS[i]); 13917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 14017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 14117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 142b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; 1434d03abcd49af490dba3850d341b955dd72f24959Robin Lee @Mock private UserManager mUserManager; 1444d03abcd49af490dba3850d341b955dd72f24959Robin Lee @Mock private PackageManager mPackageManager; 1454d03abcd49af490dba3850d341b955dd72f24959Robin Lee @Mock private INetworkManagementService mNetService; 14617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee @Mock private AppOpsManager mAppOps; 147de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak @Mock private NotificationManager mNotificationManager; 148b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee @Mock private Vpn.SystemServices mSystemServices; 14972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey @Mock private ConnectivityManager mConnectivityManager; 1504d03abcd49af490dba3850d341b955dd72f24959Robin Lee 1514a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Before 1524d03abcd49af490dba3850d341b955dd72f24959Robin Lee public void setUp() throws Exception { 1534d03abcd49af490dba3850d341b955dd72f24959Robin Lee MockitoAnnotations.initMocks(this); 154c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 1554d03abcd49af490dba3850d341b955dd72f24959Robin Lee when(mContext.getPackageManager()).thenReturn(mPackageManager); 15617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee setMockedPackages(mPackages); 157c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 158de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak when(mContext.getPackageName()).thenReturn(Vpn.class.getPackage().getName()); 1594d03abcd49af490dba3850d341b955dd72f24959Robin Lee when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager); 16017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps); 161de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE))) 162de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak .thenReturn(mNotificationManager); 16372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE))) 16472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .thenReturn(mConnectivityManager); 165c17f50f83d3e35f338095df6065426f2f304a1dcCharles He when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)) 166c17f50f83d3e35f338095df6065426f2f304a1dcCharles He .thenReturn(Resources.getSystem().getString( 167c17f50f83d3e35f338095df6065426f2f304a1dcCharles He R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)); 168b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee 169b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee // Used by {@link Notification.Builder} 170b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee ApplicationInfo applicationInfo = new ApplicationInfo(); 171a0a87e810870b696239f0371d33de924f84cb431Charles He applicationInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; 172b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee when(mContext.getApplicationInfo()).thenReturn(applicationInfo); 173b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee 1744d03abcd49af490dba3850d341b955dd72f24959Robin Lee doNothing().when(mNetService).registerObserver(any()); 1754d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 1764d03abcd49af490dba3850d341b955dd72f24959Robin Lee 1774a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 1784d03abcd49af490dba3850d341b955dd72f24959Robin Lee public void testRestrictedProfilesAreAddedToVpn() { 1794d03abcd49af490dba3850d341b955dd72f24959Robin Lee setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB); 1804d03abcd49af490dba3850d341b955dd72f24959Robin Lee 181b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 1824d03abcd49af490dba3850d341b955dd72f24959Robin Lee final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, 1834d03abcd49af490dba3850d341b955dd72f24959Robin Lee null, null); 1844d03abcd49af490dba3850d341b955dd72f24959Robin Lee 1854d03abcd49af490dba3850d341b955dd72f24959Robin Lee assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { 1864d03abcd49af490dba3850d341b955dd72f24959Robin Lee UidRange.createForUser(primaryUser.id), 1874d03abcd49af490dba3850d341b955dd72f24959Robin Lee UidRange.createForUser(restrictedProfileA.id) 1884d03abcd49af490dba3850d341b955dd72f24959Robin Lee })), ranges); 1894d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 1904d03abcd49af490dba3850d341b955dd72f24959Robin Lee 1914a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 1924d03abcd49af490dba3850d341b955dd72f24959Robin Lee public void testManagedProfilesAreNotAddedToVpn() { 1934d03abcd49af490dba3850d341b955dd72f24959Robin Lee setMockedUsers(primaryUser, managedProfileA); 1944d03abcd49af490dba3850d341b955dd72f24959Robin Lee 195b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 1964d03abcd49af490dba3850d341b955dd72f24959Robin Lee final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, 1974d03abcd49af490dba3850d341b955dd72f24959Robin Lee null, null); 1984d03abcd49af490dba3850d341b955dd72f24959Robin Lee 1994d03abcd49af490dba3850d341b955dd72f24959Robin Lee assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { 2004d03abcd49af490dba3850d341b955dd72f24959Robin Lee UidRange.createForUser(primaryUser.id) 2014d03abcd49af490dba3850d341b955dd72f24959Robin Lee })), ranges); 2024d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 2034d03abcd49af490dba3850d341b955dd72f24959Robin Lee 2044a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 2054d03abcd49af490dba3850d341b955dd72f24959Robin Lee public void testAddUserToVpnOnlyAddsOneUser() { 2064d03abcd49af490dba3850d341b955dd72f24959Robin Lee setMockedUsers(primaryUser, restrictedProfileA, managedProfileA); 2074d03abcd49af490dba3850d341b955dd72f24959Robin Lee 208b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 2094d03abcd49af490dba3850d341b955dd72f24959Robin Lee final Set<UidRange> ranges = new ArraySet<>(); 2104d03abcd49af490dba3850d341b955dd72f24959Robin Lee vpn.addUserToRanges(ranges, primaryUser.id, null, null); 2114d03abcd49af490dba3850d341b955dd72f24959Robin Lee 2124d03abcd49af490dba3850d341b955dd72f24959Robin Lee assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { 2134d03abcd49af490dba3850d341b955dd72f24959Robin Lee UidRange.createForUser(primaryUser.id) 2144d03abcd49af490dba3850d341b955dd72f24959Robin Lee })), ranges); 2154d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 2164d03abcd49af490dba3850d341b955dd72f24959Robin Lee 2174a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 2184d03abcd49af490dba3850d341b955dd72f24959Robin Lee public void testUidWhiteAndBlacklist() throws Exception { 219b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 2204d03abcd49af490dba3850d341b955dd72f24959Robin Lee final UidRange user = UidRange.createForUser(primaryUser.id); 22117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; 2224d03abcd49af490dba3850d341b955dd72f24959Robin Lee 2234d03abcd49af490dba3850d341b955dd72f24959Robin Lee // Whitelist 2244d03abcd49af490dba3850d341b955dd72f24959Robin Lee final Set<UidRange> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, 22517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee Arrays.asList(packages), null); 2264d03abcd49af490dba3850d341b955dd72f24959Robin Lee assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { 22717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[0], user.start + PKG_UIDS[0]), 22817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]) 2294d03abcd49af490dba3850d341b955dd72f24959Robin Lee })), allow); 2304d03abcd49af490dba3850d341b955dd72f24959Robin Lee 2314d03abcd49af490dba3850d341b955dd72f24959Robin Lee // Blacklist 2324d03abcd49af490dba3850d341b955dd72f24959Robin Lee final Set<UidRange> disallow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, 23317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee null, Arrays.asList(packages)); 2344d03abcd49af490dba3850d341b955dd72f24959Robin Lee assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { 23517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start, user.start + PKG_UIDS[0] - 1), 23617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1), 23717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee /* Empty range between UIDS[1] and UIDS[2], should be excluded, */ 23817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[2] + 1, user.stop) 2394d03abcd49af490dba3850d341b955dd72f24959Robin Lee })), disallow); 2404d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 2414d03abcd49af490dba3850d341b955dd72f24959Robin Lee 2424a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 24317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee public void testLockdownChangingPackage() throws Exception { 244b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 24517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final UidRange user = UidRange.createForUser(primaryUser.id); 24617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 24717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Default state. 248de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]); 24917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 25017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Set always-on without lockdown. 25117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false)); 252de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]); 25317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 25417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Set always-on with lockdown. 25517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true)); 25617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] { 25717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start, user.start + PKG_UIDS[1] - 1), 25817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[1] + 1, user.stop) 25917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee })); 260de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]); 261de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertUnblocked(vpn, user.start + PKG_UIDS[1]); 26217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 26317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Switch to another app. 26417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true)); 26517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] { 26617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start, user.start + PKG_UIDS[1] - 1), 26717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[1] + 1, user.stop) 26817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee })); 26917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] { 27017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start, user.start + PKG_UIDS[3] - 1), 27117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[3] + 1, user.stop) 27217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee })); 273de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]); 274de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertUnblocked(vpn, user.start + PKG_UIDS[3]); 27517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 27617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 2774a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 27817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee public void testLockdownAddingAProfile() throws Exception { 279b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 28017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee setMockedUsers(primaryUser); 28117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 28217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Make a copy of the restricted profile, as we're going to mark it deleted halfway through. 28317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final UserInfo tempProfile = new UserInfo(restrictedProfileA.id, restrictedProfileA.name, 28417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee restrictedProfileA.flags); 28517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee tempProfile.restrictedProfileParentId = primaryUser.id; 28617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 28717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final UidRange user = UidRange.createForUser(primaryUser.id); 28817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final UidRange profile = UidRange.createForUser(tempProfile.id); 28917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 29017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Set lockdown. 29117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true)); 29217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] { 29317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start, user.start + PKG_UIDS[3] - 1), 29417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(user.start + PKG_UIDS[3] + 1, user.stop) 29517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee })); 29617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 29717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Verify restricted user isn't affected at first. 298de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertUnblocked(vpn, profile.start + PKG_UIDS[0]); 29917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 30017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Add the restricted user. 30117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee setMockedUsers(primaryUser, tempProfile); 30217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee vpn.onUserAdded(tempProfile.id); 30317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] { 30417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(profile.start, profile.start + PKG_UIDS[3] - 1), 30517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(profile.start + PKG_UIDS[3] + 1, profile.stop) 30617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee })); 30717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 30817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee // Remove the restricted user. 30917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee tempProfile.partial = true; 31017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee vpn.onUserRemoved(tempProfile.id); 31117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] { 31217e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(profile.start, profile.start + PKG_UIDS[3] - 1), 31317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee new UidRange(profile.start + PKG_UIDS[3] + 1, profile.stop) 31417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee })); 31517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 31617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 3174a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 318c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee public void testLockdownRuleRepeatability() throws Exception { 319c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee final Vpn vpn = createVpn(primaryUser.id); 320c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 321c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // Given legacy lockdown is already enabled, 322c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.setLockdown(true); 323c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee verify(mNetService, times(1)).setAllowOnlyVpnForUids( 324c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee eq(true), aryEq(new UidRange[] {UidRange.createForUser(primaryUser.id)})); 325c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 326c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // Enabling legacy lockdown twice should do nothing. 327c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.setLockdown(true); 328c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee verify(mNetService, times(1)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class)); 329c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 330c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // And disabling should remove the rules exactly once. 331c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.setLockdown(false); 332c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee verify(mNetService, times(1)).setAllowOnlyVpnForUids( 333c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee eq(false), aryEq(new UidRange[] {UidRange.createForUser(primaryUser.id)})); 334c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 335c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // Removing the lockdown again should have no effect. 336c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.setLockdown(false); 337c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee verify(mNetService, times(2)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class)); 338c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee } 339c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 3404a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 341c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee public void testLockdownRuleReversibility() throws Exception { 342c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee final Vpn vpn = createVpn(primaryUser.id); 343c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 344c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee final UidRange[] entireUser = { 345c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee UidRange.createForUser(primaryUser.id) 346c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee }; 347c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee final UidRange[] exceptPkg0 = { 348c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee new UidRange(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1), 349c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee new UidRange(entireUser[0].start + PKG_UIDS[0] + 1, entireUser[0].stop) 350c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee }; 351c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 352c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee final InOrder order = inOrder(mNetService); 353c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 354c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // Given lockdown is enabled with no package (legacy VPN), 355c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.setLockdown(true); 356c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser)); 357c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 358c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // When a new VPN package is set the rules should change to cover that package. 359c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.prepare(null, PKGS[0]); 360c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee order.verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(entireUser)); 361c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(exceptPkg0)); 362c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 363c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee // When that VPN package is unset, everything should be undone again in reverse. 364c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee vpn.prepare(null, VpnConfig.LEGACY_VPN); 365c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee order.verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(exceptPkg0)); 366c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser)); 367c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee } 368c3736bc10da63d6a351d3f8e7781ff1d67ecc9a6Robin Lee 3694a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 370a0a87e810870b696239f0371d33de924f84cb431Charles He public void testIsAlwaysOnPackageSupported() throws Exception { 371a0a87e810870b696239f0371d33de924f84cb431Charles He final Vpn vpn = createVpn(primaryUser.id); 372a0a87e810870b696239f0371d33de924f84cb431Charles He 373a0a87e810870b696239f0371d33de924f84cb431Charles He ApplicationInfo appInfo = new ApplicationInfo(); 374a0a87e810870b696239f0371d33de924f84cb431Charles He when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(primaryUser.id))) 375a0a87e810870b696239f0371d33de924f84cb431Charles He .thenReturn(appInfo); 376a0a87e810870b696239f0371d33de924f84cb431Charles He 377a0a87e810870b696239f0371d33de924f84cb431Charles He ServiceInfo svcInfo = new ServiceInfo(); 378a0a87e810870b696239f0371d33de924f84cb431Charles He ResolveInfo resInfo = new ResolveInfo(); 379a0a87e810870b696239f0371d33de924f84cb431Charles He resInfo.serviceInfo = svcInfo; 380a0a87e810870b696239f0371d33de924f84cb431Charles He when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA), 381a0a87e810870b696239f0371d33de924f84cb431Charles He eq(primaryUser.id))) 382a0a87e810870b696239f0371d33de924f84cb431Charles He .thenReturn(Collections.singletonList(resInfo)); 383a0a87e810870b696239f0371d33de924f84cb431Charles He 384a0a87e810870b696239f0371d33de924f84cb431Charles He // null package name should return false 385a0a87e810870b696239f0371d33de924f84cb431Charles He assertFalse(vpn.isAlwaysOnPackageSupported(null)); 386a0a87e810870b696239f0371d33de924f84cb431Charles He 387a0a87e810870b696239f0371d33de924f84cb431Charles He // Pre-N apps are not supported 388a0a87e810870b696239f0371d33de924f84cb431Charles He appInfo.targetSdkVersion = VERSION_CODES.M; 389a0a87e810870b696239f0371d33de924f84cb431Charles He assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); 390a0a87e810870b696239f0371d33de924f84cb431Charles He 391a0a87e810870b696239f0371d33de924f84cb431Charles He // N+ apps are supported by default 392a0a87e810870b696239f0371d33de924f84cb431Charles He appInfo.targetSdkVersion = VERSION_CODES.N; 393a0a87e810870b696239f0371d33de924f84cb431Charles He assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0])); 394a0a87e810870b696239f0371d33de924f84cb431Charles He 395a0a87e810870b696239f0371d33de924f84cb431Charles He // Apps that opt out explicitly are not supported 396a0a87e810870b696239f0371d33de924f84cb431Charles He appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; 397a0a87e810870b696239f0371d33de924f84cb431Charles He Bundle metaData = new Bundle(); 3985da5ae3b96769735a2dc5abe265101df545be828Charles He metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false); 399a0a87e810870b696239f0371d33de924f84cb431Charles He svcInfo.metaData = metaData; 400a0a87e810870b696239f0371d33de924f84cb431Charles He assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); 401a0a87e810870b696239f0371d33de924f84cb431Charles He } 402a0a87e810870b696239f0371d33de924f84cb431Charles He 4034a0c5d7ef7144280fe8a209a871bbd4ef90d6368Hugo Benichi @Test 404de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak public void testNotificationShownForAlwaysOnApp() { 405b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final UserHandle userHandle = UserHandle.of(primaryUser.id); 406b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final Vpn vpn = createVpn(primaryUser.id); 407de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak setMockedUsers(primaryUser); 408de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 409b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee final InOrder order = inOrder(mNotificationManager); 410b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee 411de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak // Don't show a notification for regular disconnected states. 412de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak vpn.updateState(DetailedState.DISCONNECTED, TAG); 413b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee order.verify(mNotificationManager, atLeastOnce()) 414b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee .cancelAsUser(anyString(), anyInt(), eq(userHandle)); 415de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 416de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak // Start showing a notification for disconnected once always-on. 417de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak vpn.setAlwaysOnPackage(PKGS[0], false); 418b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee order.verify(mNotificationManager) 419b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle)); 420de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 421de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak // Stop showing the notification once connected. 422de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak vpn.updateState(DetailedState.CONNECTED, TAG); 423b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle)); 424de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 425de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak // Show the notification if we disconnect again. 426de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak vpn.updateState(DetailedState.DISCONNECTED, TAG); 427b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee order.verify(mNotificationManager) 428b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle)); 429de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 430de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak // Notification should be cleared after unsetting always-on package. 431de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak vpn.setAlwaysOnPackage(null, false); 432b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle)); 433de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak } 434de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 43572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey @Test 43672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey public void testCapabilities() { 43772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey final Vpn vpn = createVpn(primaryUser.id); 43872f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey setMockedUsers(primaryUser); 43972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 44072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey final Network mobile = new Network(1); 44172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey final Network wifi = new Network(2); 44272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 44372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey final Map<Network, NetworkCapabilities> networks = new HashMap<>(); 44472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey networks.put(mobile, new NetworkCapabilities() 44572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .addTransportType(TRANSPORT_CELLULAR) 44672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .addCapability(NET_CAPABILITY_INTERNET) 44772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .addCapability(NET_CAPABILITY_NOT_METERED) 4489b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkey .addCapability(NET_CAPABILITY_NOT_CONGESTED) 44972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .setLinkDownstreamBandwidthKbps(10)); 45072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey networks.put(wifi, new NetworkCapabilities() 45172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .addTransportType(TRANSPORT_WIFI) 45272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .addCapability(NET_CAPABILITY_INTERNET) 45372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .addCapability(NET_CAPABILITY_NOT_ROAMING) 4549b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkey .addCapability(NET_CAPABILITY_NOT_CONGESTED) 45572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey .setLinkUpstreamBandwidthKbps(20)); 45672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey setMockedNetworks(networks); 45772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 45872f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey final NetworkCapabilities caps = new NetworkCapabilities(); 45972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 46072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey Vpn.updateCapabilities(mConnectivityManager, new Network[] { }, caps); 46172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_VPN)); 46272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); 46372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasTransport(TRANSPORT_WIFI)); 46472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps()); 46572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps()); 46672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 46772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 4689b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 46972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 47072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile }, caps); 47172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_VPN)); 47272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_CELLULAR)); 47372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasTransport(TRANSPORT_WIFI)); 47472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(10, caps.getLinkDownstreamBandwidthKbps()); 47572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps()); 47672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 47772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 4789b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 47972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 48072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey Vpn.updateCapabilities(mConnectivityManager, new Network[] { wifi }, caps); 48172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_VPN)); 48272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasTransport(TRANSPORT_CELLULAR)); 48372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_WIFI)); 48472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps()); 48572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); 48672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 48772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 4889b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 48972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 49072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile, wifi }, caps); 49172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_VPN)); 49272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_CELLULAR)); 49372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertTrue(caps.hasTransport(TRANSPORT_WIFI)); 49472f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(10, caps.getLinkDownstreamBandwidthKbps()); 49572f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); 49672f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); 49772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); 4989b2a10f55d1659895e20ec0b88dd023ae18770ebJeff Sharkey assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); 49972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey } 50072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 5014d03abcd49af490dba3850d341b955dd72f24959Robin Lee /** 502de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak * Mock some methods of vpn object. 5034d03abcd49af490dba3850d341b955dd72f24959Robin Lee */ 504b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee private Vpn createVpn(@UserIdInt int userId) { 505b8c2a2b85052479cb6affe2d4a8240e78198e2d5Robin Lee return new Vpn(Looper.myLooper(), mContext, mNetService, userId, mSystemServices); 506de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak } 507de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak 508de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak private static void assertBlocked(Vpn vpn, int... uids) { 509de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak for (int uid : uids) { 510de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertTrue("Uid " + uid + " should be blocked", vpn.isBlockingUid(uid)); 51117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 512de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak } 51317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee 514de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak private static void assertUnblocked(Vpn vpn, int... uids) { 515de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak for (int uid : uids) { 516de7f7d195eec64802b7b6eee819c699f1a7d6951Tony Mak assertFalse("Uid " + uid + " should not be blocked", vpn.isBlockingUid(uid)); 51717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 5184d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 5194d03abcd49af490dba3850d341b955dd72f24959Robin Lee 5204d03abcd49af490dba3850d341b955dd72f24959Robin Lee /** 5214d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Populate {@link #mUserManager} with a list of fake users. 5224d03abcd49af490dba3850d341b955dd72f24959Robin Lee */ 5234d03abcd49af490dba3850d341b955dd72f24959Robin Lee private void setMockedUsers(UserInfo... users) { 5244d03abcd49af490dba3850d341b955dd72f24959Robin Lee final Map<Integer, UserInfo> userMap = new ArrayMap<>(); 5254d03abcd49af490dba3850d341b955dd72f24959Robin Lee for (UserInfo user : users) { 5264d03abcd49af490dba3850d341b955dd72f24959Robin Lee userMap.put(user.id, user); 5274d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 5284d03abcd49af490dba3850d341b955dd72f24959Robin Lee 52917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee /** 53017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee * @see UserManagerService#getUsers(boolean) 53117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee */ 5324d03abcd49af490dba3850d341b955dd72f24959Robin Lee doAnswer(invocation -> { 53317e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final boolean excludeDying = (boolean) invocation.getArguments()[0]; 53417e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee final ArrayList<UserInfo> result = new ArrayList<>(users.length); 53517e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee for (UserInfo ui : users) { 53617e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee if (!excludeDying || (ui.isEnabled() && !ui.partial)) { 53717e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee result.add(ui); 53817e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 53917e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee } 54017e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee return result; 54117e6183b85ba3038acb935aaa01415058b2e6dddRobin Lee }).when(mUserManager).getUsers(anyBoolean()); 5424d03abcd49af490dba3850d341b955dd72f24959Robin Lee 5434d03abcd49af490dba3850d341b955dd72f24959Robin Lee doAnswer(invocation -> { 5444d03abcd49af490dba3850d341b955dd72f24959Robin Lee final int id = (int) invocation.getArguments()[0]; 5454d03abcd49af490dba3850d341b955dd72f24959Robin Lee return userMap.get(id); 5464d03abcd49af490dba3850d341b955dd72f24959Robin Lee }).when(mUserManager).getUserInfo(anyInt()); 5474d03abcd49af490dba3850d341b955dd72f24959Robin Lee 5484d03abcd49af490dba3850d341b955dd72f24959Robin Lee doAnswer(invocation -> { 5494d03abcd49af490dba3850d341b955dd72f24959Robin Lee final int id = (int) invocation.getArguments()[0]; 5504d03abcd49af490dba3850d341b955dd72f24959Robin Lee return (userMap.get(id).flags & UserInfo.FLAG_ADMIN) != 0; 5514d03abcd49af490dba3850d341b955dd72f24959Robin Lee }).when(mUserManager).canHaveRestrictedProfile(anyInt()); 5524d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 5534d03abcd49af490dba3850d341b955dd72f24959Robin Lee 5544d03abcd49af490dba3850d341b955dd72f24959Robin Lee /** 5554d03abcd49af490dba3850d341b955dd72f24959Robin Lee * Populate {@link #mPackageManager} with a fake packageName-to-UID mapping. 5564d03abcd49af490dba3850d341b955dd72f24959Robin Lee */ 5574d03abcd49af490dba3850d341b955dd72f24959Robin Lee private void setMockedPackages(final Map<String, Integer> packages) { 5584d03abcd49af490dba3850d341b955dd72f24959Robin Lee try { 5594d03abcd49af490dba3850d341b955dd72f24959Robin Lee doAnswer(invocation -> { 5604d03abcd49af490dba3850d341b955dd72f24959Robin Lee final String appName = (String) invocation.getArguments()[0]; 5614d03abcd49af490dba3850d341b955dd72f24959Robin Lee final int userId = (int) invocation.getArguments()[1]; 5624d03abcd49af490dba3850d341b955dd72f24959Robin Lee return UserHandle.getUid(userId, packages.get(appName)); 5634d03abcd49af490dba3850d341b955dd72f24959Robin Lee }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt()); 5644d03abcd49af490dba3850d341b955dd72f24959Robin Lee } catch (Exception e) { 5654d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 5664d03abcd49af490dba3850d341b955dd72f24959Robin Lee } 56772f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey 56872f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey private void setMockedNetworks(final Map<Network, NetworkCapabilities> networks) { 56972f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey doAnswer(invocation -> { 57072f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey final Network network = (Network) invocation.getArguments()[0]; 57172f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey return networks.get(network); 57272f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey }).when(mConnectivityManager).getNetworkCapabilities(any()); 57372f9c42b9e59761a28d6b32c42f65de57c98daedJeff Sharkey } 574adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 575adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // Need multiple copies of this, but Java's Stream objects can't be reused or 576adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // duplicated. 577adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean private Stream<String> publicIpV4Routes() { 578adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean return Stream.of( 579adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "0.0.0.0/5", "8.0.0.0/7", "11.0.0.0/8", "12.0.0.0/6", "16.0.0.0/4", 580adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "32.0.0.0/3", "64.0.0.0/2", "128.0.0.0/3", "160.0.0.0/5", "168.0.0.0/6", 581adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "172.0.0.0/12", "172.32.0.0/11", "172.64.0.0/10", "172.128.0.0/9", 582adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "173.0.0.0/8", "174.0.0.0/7", "176.0.0.0/4", "192.0.0.0/9", "192.128.0.0/11", 583adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "192.160.0.0/13", "192.169.0.0/16", "192.170.0.0/15", "192.172.0.0/14", 584adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "192.176.0.0/12", "192.192.0.0/10", "193.0.0.0/8", "194.0.0.0/7", 585adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "196.0.0.0/6", "200.0.0.0/5", "208.0.0.0/4"); 586adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean } 587adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 588adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean private Stream<String> publicIpV6Routes() { 589adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean return Stream.of( 590adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "::/1", "8000::/2", "c000::/3", "e000::/4", "f000::/5", "f800::/6", 591adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean "fe00::/8", "2605:ef80:e:af1d::/64"); 592adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean } 593adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 594adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean @Test 595adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean public void testProvidesRoutesToMostDestinations() { 596adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean final LinkProperties lp = new LinkProperties(); 597adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 598adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // Default route provides routes to all IPv4 destinations. 599adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"))); 600adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 601adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 602adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // Empty LP provides routes to no destination 603adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.clear(); 604adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertFalse(Vpn.providesRoutesToMostDestinations(lp)); 605adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 606adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // All IPv4 routes except for local networks. This is the case most relevant 607adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // to this function. It provides routes to almost the entire space. 608adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // (clone the stream so that we can reuse it later) 609adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean publicIpV4Routes().forEach(s -> lp.addRoute(new RouteInfo(new IpPrefix(s)))); 610adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 611adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 612adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // Removing a 16-bit prefix, which is 65536 addresses. This is still enough to 613adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // provide routes to "most" destinations. 614adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.removeRoute(new RouteInfo(new IpPrefix("192.169.0.0/16"))); 615adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 616adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 617adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // Remove the /2 route, which represent a quarter of the available routing space. 618adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // This LP does not provides routes to "most" destinations any more. 619adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.removeRoute(new RouteInfo(new IpPrefix("64.0.0.0/2"))); 620adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertFalse(Vpn.providesRoutesToMostDestinations(lp)); 621adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 622adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.clear(); 623adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean publicIpV6Routes().forEach(s -> lp.addRoute(new RouteInfo(new IpPrefix(s)))); 624adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 625adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 626adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.removeRoute(new RouteInfo(new IpPrefix("::/1"))); 627adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertFalse(Vpn.providesRoutesToMostDestinations(lp)); 628adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 629adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // V6 does not provide sufficient coverage but v4 does 630adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean publicIpV4Routes().forEach(s -> lp.addRoute(new RouteInfo(new IpPrefix(s)))); 631adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 632adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 633adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // V4 still does 634adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.removeRoute(new RouteInfo(new IpPrefix("192.169.0.0/16"))); 635adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 636adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 637adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // V4 does not any more 638adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.removeRoute(new RouteInfo(new IpPrefix("64.0.0.0/2"))); 639adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertFalse(Vpn.providesRoutesToMostDestinations(lp)); 640adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean 641adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean // V4 does not, but V6 has sufficient coverage again 642adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean lp.addRoute(new RouteInfo(new IpPrefix("::/1"))); 643adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 644adbf1d029b753fabc2a7a5ad3b22d3d416cecdd9Chalard Jean } 645507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean 646507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean @Test 647507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean public void testDoesNotLockUpWithTooManyRoutes() { 648507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean final LinkProperties lp = new LinkProperties(); 649507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean final byte[] ad = new byte[4]; 650507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean // Actually evaluating this many routes under 1500ms is impossible on 651507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean // current hardware and for some time, as the algorithm is O(n²). 652507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean // Make sure the system has a safeguard against this and does not 653507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean // lock up. 654507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean final int MAX_ROUTES = 4000; 655507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean final long MAX_ALLOWED_TIME_MS = 1500; 656507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean for (int i = 0; i < MAX_ROUTES; ++i) { 657507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean ad[0] = (byte)((i >> 24) & 0xFF); 658507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean ad[1] = (byte)((i >> 16) & 0xFF); 659507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean ad[2] = (byte)((i >> 8) & 0xFF); 660507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean ad[3] = (byte)(i & 0xFF); 661507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean try { 662507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.getByAddress(ad), 32))); 663507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean } catch (UnknownHostException e) { 664507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean // UnknownHostException is only thrown for an address of illegal length, 665507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean // which can't happen in the case above. 666507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean } 667507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean } 668507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean final long start = SystemClock.currentThreadTimeMillis(); 669507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean assertTrue(Vpn.providesRoutesToMostDestinations(lp)); 670507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean final long end = SystemClock.currentThreadTimeMillis(); 671507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean assertTrue(end - start < MAX_ALLOWED_TIME_MS); 672507754a81e0b9d871e59fe9621c2a5d57befff90Chalard Jean } 6734d03abcd49af490dba3850d341b955dd72f24959Robin Lee} 674