blob: 296cb76560af40ce1f0fdf47ef51f9a7d4aac055 [file] [log] [blame]
Robin Lee4d03abc2016-05-09 12:32:27 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.connectivity;
18
19import static android.content.pm.UserInfo.FLAG_ADMIN;
20import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
21import static android.content.pm.UserInfo.FLAG_PRIMARY;
22import static android.content.pm.UserInfo.FLAG_RESTRICTED;
Robin Lee17e61832016-05-09 13:46:28 +010023import static org.mockito.AdditionalMatchers.*;
Robin Lee4d03abc2016-05-09 12:32:27 +010024import static org.mockito.Mockito.*;
25
26import android.annotation.UserIdInt;
Robin Lee17e61832016-05-09 13:46:28 +010027import android.app.AppOpsManager;
Tony Makde7f7d12016-06-30 11:19:20 +010028import android.app.NotificationManager;
Robin Lee4d03abc2016-05-09 12:32:27 +010029import android.content.Context;
Robin Leeb8c2a2b2017-03-10 16:17:06 +000030import android.content.pm.ApplicationInfo;
Robin Lee4d03abc2016-05-09 12:32:27 +010031import android.content.pm.PackageManager;
Charles He36738632017-05-15 17:07:18 +010032import android.content.pm.ResolveInfo;
33import android.content.pm.ServiceInfo;
Robin Lee4d03abc2016-05-09 12:32:27 +010034import android.content.pm.UserInfo;
Tony Makde7f7d12016-06-30 11:19:20 +010035import android.net.NetworkInfo.DetailedState;
Robin Lee4d03abc2016-05-09 12:32:27 +010036import android.net.UidRange;
Charles He36738632017-05-15 17:07:18 +010037import android.net.VpnService;
38import android.os.Build.VERSION_CODES;
39import android.os.Bundle;
Robin Lee4d03abc2016-05-09 12:32:27 +010040import android.os.INetworkManagementService;
41import android.os.Looper;
42import android.os.UserHandle;
43import android.os.UserManager;
44import android.test.AndroidTestCase;
45import android.test.suitebuilder.annotation.SmallTest;
46import android.util.ArrayMap;
47import android.util.ArraySet;
48
Robin Leec3736bc2017-03-10 16:19:54 +000049import com.android.internal.net.VpnConfig;
50
Robin Leeb8c2a2b2017-03-10 16:17:06 +000051import org.mockito.Answers;
Tony Makde7f7d12016-06-30 11:19:20 +010052import org.mockito.InOrder;
Robin Lee4d03abc2016-05-09 12:32:27 +010053import org.mockito.Mock;
54import org.mockito.MockitoAnnotations;
55
Charles He36738632017-05-15 17:07:18 +010056import java.util.ArrayList;
57import java.util.Arrays;
58import java.util.Collections;
59import java.util.Map;
60import java.util.Set;
61
Robin Lee4d03abc2016-05-09 12:32:27 +010062/**
63 * Tests for {@link Vpn}.
64 *
65 * Build, install and run with:
Charles He36738632017-05-15 17:07:18 +010066 * runtest --path java/com/android/server/connectivity/VpnTest.java
Robin Lee4d03abc2016-05-09 12:32:27 +010067 */
68public class VpnTest extends AndroidTestCase {
69 private static final String TAG = "VpnTest";
70
71 // Mock users
72 static final UserInfo primaryUser = new UserInfo(27, "Primary", FLAG_ADMIN | FLAG_PRIMARY);
73 static final UserInfo secondaryUser = new UserInfo(15, "Secondary", FLAG_ADMIN);
74 static final UserInfo restrictedProfileA = new UserInfo(40, "RestrictedA", FLAG_RESTRICTED);
75 static final UserInfo restrictedProfileB = new UserInfo(42, "RestrictedB", FLAG_RESTRICTED);
76 static final UserInfo managedProfileA = new UserInfo(45, "ManagedA", FLAG_MANAGED_PROFILE);
77 static {
78 restrictedProfileA.restrictedProfileParentId = primaryUser.id;
79 restrictedProfileB.restrictedProfileParentId = secondaryUser.id;
80 managedProfileA.profileGroupId = primaryUser.id;
81 }
82
Robin Lee17e61832016-05-09 13:46:28 +010083 /**
84 * Names and UIDs for some fake packages. Important points:
85 * - UID is ordered increasing.
86 * - One pair of packages have consecutive UIDs.
87 */
88 static final String[] PKGS = {"com.example", "org.example", "net.example", "web.vpn"};
89 static final int[] PKG_UIDS = {66, 77, 78, 400};
90
91 // Mock packages
92 static final Map<String, Integer> mPackages = new ArrayMap<>();
93 static {
94 for (int i = 0; i < PKGS.length; i++) {
95 mPackages.put(PKGS[i], PKG_UIDS[i]);
96 }
97 }
98
Robin Leeb8c2a2b2017-03-10 16:17:06 +000099 @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
Robin Lee4d03abc2016-05-09 12:32:27 +0100100 @Mock private UserManager mUserManager;
101 @Mock private PackageManager mPackageManager;
102 @Mock private INetworkManagementService mNetService;
Robin Lee17e61832016-05-09 13:46:28 +0100103 @Mock private AppOpsManager mAppOps;
Tony Makde7f7d12016-06-30 11:19:20 +0100104 @Mock private NotificationManager mNotificationManager;
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000105 @Mock private Vpn.SystemServices mSystemServices;
Robin Lee4d03abc2016-05-09 12:32:27 +0100106
107 @Override
108 public void setUp() throws Exception {
109 MockitoAnnotations.initMocks(this);
Robin Leec3736bc2017-03-10 16:19:54 +0000110
Robin Lee4d03abc2016-05-09 12:32:27 +0100111 when(mContext.getPackageManager()).thenReturn(mPackageManager);
Robin Lee17e61832016-05-09 13:46:28 +0100112 setMockedPackages(mPackages);
Robin Leec3736bc2017-03-10 16:19:54 +0000113
Tony Makde7f7d12016-06-30 11:19:20 +0100114 when(mContext.getPackageName()).thenReturn(Vpn.class.getPackage().getName());
Robin Lee4d03abc2016-05-09 12:32:27 +0100115 when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
Robin Lee17e61832016-05-09 13:46:28 +0100116 when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
Tony Makde7f7d12016-06-30 11:19:20 +0100117 when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
118 .thenReturn(mNotificationManager);
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000119
120 // Used by {@link Notification.Builder}
121 ApplicationInfo applicationInfo = new ApplicationInfo();
Charles He36738632017-05-15 17:07:18 +0100122 applicationInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT;
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000123 when(mContext.getApplicationInfo()).thenReturn(applicationInfo);
124
Robin Lee4d03abc2016-05-09 12:32:27 +0100125 doNothing().when(mNetService).registerObserver(any());
126 }
127
128 @SmallTest
129 public void testRestrictedProfilesAreAddedToVpn() {
130 setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
131
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000132 final Vpn vpn = createVpn(primaryUser.id);
Robin Lee4d03abc2016-05-09 12:32:27 +0100133 final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
134 null, null);
135
136 assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
137 UidRange.createForUser(primaryUser.id),
138 UidRange.createForUser(restrictedProfileA.id)
139 })), ranges);
140 }
141
142 @SmallTest
143 public void testManagedProfilesAreNotAddedToVpn() {
144 setMockedUsers(primaryUser, managedProfileA);
145
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000146 final Vpn vpn = createVpn(primaryUser.id);
Robin Lee4d03abc2016-05-09 12:32:27 +0100147 final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
148 null, null);
149
150 assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
151 UidRange.createForUser(primaryUser.id)
152 })), ranges);
153 }
154
155 @SmallTest
156 public void testAddUserToVpnOnlyAddsOneUser() {
157 setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
158
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000159 final Vpn vpn = createVpn(primaryUser.id);
Robin Lee4d03abc2016-05-09 12:32:27 +0100160 final Set<UidRange> ranges = new ArraySet<>();
161 vpn.addUserToRanges(ranges, primaryUser.id, null, null);
162
163 assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
164 UidRange.createForUser(primaryUser.id)
165 })), ranges);
166 }
167
168 @SmallTest
169 public void testUidWhiteAndBlacklist() throws Exception {
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000170 final Vpn vpn = createVpn(primaryUser.id);
Robin Lee4d03abc2016-05-09 12:32:27 +0100171 final UidRange user = UidRange.createForUser(primaryUser.id);
Robin Lee17e61832016-05-09 13:46:28 +0100172 final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
Robin Lee4d03abc2016-05-09 12:32:27 +0100173
174 // Whitelist
175 final Set<UidRange> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
Robin Lee17e61832016-05-09 13:46:28 +0100176 Arrays.asList(packages), null);
Robin Lee4d03abc2016-05-09 12:32:27 +0100177 assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
Robin Lee17e61832016-05-09 13:46:28 +0100178 new UidRange(user.start + PKG_UIDS[0], user.start + PKG_UIDS[0]),
179 new UidRange(user.start + PKG_UIDS[1], user.start + PKG_UIDS[2])
Robin Lee4d03abc2016-05-09 12:32:27 +0100180 })), allow);
181
182 // Blacklist
183 final Set<UidRange> disallow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
Robin Lee17e61832016-05-09 13:46:28 +0100184 null, Arrays.asList(packages));
Robin Lee4d03abc2016-05-09 12:32:27 +0100185 assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
Robin Lee17e61832016-05-09 13:46:28 +0100186 new UidRange(user.start, user.start + PKG_UIDS[0] - 1),
187 new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
188 /* Empty range between UIDS[1] and UIDS[2], should be excluded, */
189 new UidRange(user.start + PKG_UIDS[2] + 1, user.stop)
Robin Lee4d03abc2016-05-09 12:32:27 +0100190 })), disallow);
191 }
192
Robin Lee17e61832016-05-09 13:46:28 +0100193 @SmallTest
194 public void testLockdownChangingPackage() throws Exception {
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000195 final Vpn vpn = createVpn(primaryUser.id);
Robin Lee17e61832016-05-09 13:46:28 +0100196 final UidRange user = UidRange.createForUser(primaryUser.id);
197
198 // Default state.
Tony Makde7f7d12016-06-30 11:19:20 +0100199 assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
Robin Lee17e61832016-05-09 13:46:28 +0100200
201 // Set always-on without lockdown.
202 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false));
Tony Makde7f7d12016-06-30 11:19:20 +0100203 assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
Robin Lee17e61832016-05-09 13:46:28 +0100204
205 // Set always-on with lockdown.
206 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true));
207 verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
208 new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
209 new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
210 }));
Tony Makde7f7d12016-06-30 11:19:20 +0100211 assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
212 assertUnblocked(vpn, user.start + PKG_UIDS[1]);
Robin Lee17e61832016-05-09 13:46:28 +0100213
214 // Switch to another app.
215 assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true));
216 verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
217 new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
218 new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
219 }));
220 verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
221 new UidRange(user.start, user.start + PKG_UIDS[3] - 1),
222 new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
223 }));
Tony Makde7f7d12016-06-30 11:19:20 +0100224 assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
225 assertUnblocked(vpn, user.start + PKG_UIDS[3]);
Robin Lee17e61832016-05-09 13:46:28 +0100226 }
227
228 @SmallTest
229 public void testLockdownAddingAProfile() throws Exception {
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000230 final Vpn vpn = createVpn(primaryUser.id);
Robin Lee17e61832016-05-09 13:46:28 +0100231 setMockedUsers(primaryUser);
232
233 // Make a copy of the restricted profile, as we're going to mark it deleted halfway through.
234 final UserInfo tempProfile = new UserInfo(restrictedProfileA.id, restrictedProfileA.name,
235 restrictedProfileA.flags);
236 tempProfile.restrictedProfileParentId = primaryUser.id;
237
238 final UidRange user = UidRange.createForUser(primaryUser.id);
239 final UidRange profile = UidRange.createForUser(tempProfile.id);
240
241 // Set lockdown.
242 assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true));
243 verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
244 new UidRange(user.start, user.start + PKG_UIDS[3] - 1),
245 new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
246 }));
247
248 // Verify restricted user isn't affected at first.
Tony Makde7f7d12016-06-30 11:19:20 +0100249 assertUnblocked(vpn, profile.start + PKG_UIDS[0]);
Robin Lee17e61832016-05-09 13:46:28 +0100250
251 // Add the restricted user.
252 setMockedUsers(primaryUser, tempProfile);
253 vpn.onUserAdded(tempProfile.id);
254 verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
255 new UidRange(profile.start, profile.start + PKG_UIDS[3] - 1),
256 new UidRange(profile.start + PKG_UIDS[3] + 1, profile.stop)
257 }));
258
259 // Remove the restricted user.
260 tempProfile.partial = true;
261 vpn.onUserRemoved(tempProfile.id);
262 verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
263 new UidRange(profile.start, profile.start + PKG_UIDS[3] - 1),
264 new UidRange(profile.start + PKG_UIDS[3] + 1, profile.stop)
265 }));
266 }
267
Tony Makde7f7d12016-06-30 11:19:20 +0100268 @SmallTest
Robin Leec3736bc2017-03-10 16:19:54 +0000269 public void testLockdownRuleRepeatability() throws Exception {
270 final Vpn vpn = createVpn(primaryUser.id);
271
272 // Given legacy lockdown is already enabled,
273 vpn.setLockdown(true);
274 verify(mNetService, times(1)).setAllowOnlyVpnForUids(
275 eq(true), aryEq(new UidRange[] {UidRange.createForUser(primaryUser.id)}));
276
277 // Enabling legacy lockdown twice should do nothing.
278 vpn.setLockdown(true);
279 verify(mNetService, times(1)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class));
280
281 // And disabling should remove the rules exactly once.
282 vpn.setLockdown(false);
283 verify(mNetService, times(1)).setAllowOnlyVpnForUids(
284 eq(false), aryEq(new UidRange[] {UidRange.createForUser(primaryUser.id)}));
285
286 // Removing the lockdown again should have no effect.
287 vpn.setLockdown(false);
288 verify(mNetService, times(2)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class));
289 }
290
291 @SmallTest
292 public void testLockdownRuleReversibility() throws Exception {
293 final Vpn vpn = createVpn(primaryUser.id);
294
295 final UidRange[] entireUser = {
296 UidRange.createForUser(primaryUser.id)
297 };
298 final UidRange[] exceptPkg0 = {
299 new UidRange(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
300 new UidRange(entireUser[0].start + PKG_UIDS[0] + 1, entireUser[0].stop)
301 };
302
303 final InOrder order = inOrder(mNetService);
304
305 // Given lockdown is enabled with no package (legacy VPN),
306 vpn.setLockdown(true);
307 order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser));
308
309 // When a new VPN package is set the rules should change to cover that package.
310 vpn.prepare(null, PKGS[0]);
311 order.verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(entireUser));
312 order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(exceptPkg0));
313
314 // When that VPN package is unset, everything should be undone again in reverse.
315 vpn.prepare(null, VpnConfig.LEGACY_VPN);
316 order.verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(exceptPkg0));
317 order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser));
318 }
319
320 @SmallTest
Charles He36738632017-05-15 17:07:18 +0100321 public void testIsAlwaysOnPackageSupported() throws Exception {
322 final Vpn vpn = createVpn(primaryUser.id);
323
324 ApplicationInfo appInfo = new ApplicationInfo();
325 when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(primaryUser.id)))
326 .thenReturn(appInfo);
327
328 ServiceInfo svcInfo = new ServiceInfo();
329 ResolveInfo resInfo = new ResolveInfo();
330 resInfo.serviceInfo = svcInfo;
331 when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA),
332 eq(primaryUser.id)))
333 .thenReturn(Collections.singletonList(resInfo));
334
335 // null package name should return false
336 assertFalse(vpn.isAlwaysOnPackageSupported(null));
337
338 // Pre-N apps are not supported
339 appInfo.targetSdkVersion = VERSION_CODES.M;
340 assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
341
342 // N+ apps are supported by default
343 appInfo.targetSdkVersion = VERSION_CODES.N;
344 assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0]));
345
346 // Apps that opt out explicitly are not supported
347 appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT;
348 Bundle metaData = new Bundle();
Charles Hec57a01c2017-08-15 15:30:22 +0100349 metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false);
Charles He36738632017-05-15 17:07:18 +0100350 svcInfo.metaData = metaData;
351 assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0]));
352 }
353
354 @SmallTest
Tony Makde7f7d12016-06-30 11:19:20 +0100355 public void testNotificationShownForAlwaysOnApp() {
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000356 final UserHandle userHandle = UserHandle.of(primaryUser.id);
357 final Vpn vpn = createVpn(primaryUser.id);
Tony Makde7f7d12016-06-30 11:19:20 +0100358 setMockedUsers(primaryUser);
359
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000360 final InOrder order = inOrder(mNotificationManager);
361
Tony Makde7f7d12016-06-30 11:19:20 +0100362 // Don't show a notification for regular disconnected states.
363 vpn.updateState(DetailedState.DISCONNECTED, TAG);
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000364 order.verify(mNotificationManager, atLeastOnce())
365 .cancelAsUser(anyString(), anyInt(), eq(userHandle));
Tony Makde7f7d12016-06-30 11:19:20 +0100366
367 // Start showing a notification for disconnected once always-on.
368 vpn.setAlwaysOnPackage(PKGS[0], false);
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000369 order.verify(mNotificationManager)
370 .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle));
Tony Makde7f7d12016-06-30 11:19:20 +0100371
372 // Stop showing the notification once connected.
373 vpn.updateState(DetailedState.CONNECTED, TAG);
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000374 order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
Tony Makde7f7d12016-06-30 11:19:20 +0100375
376 // Show the notification if we disconnect again.
377 vpn.updateState(DetailedState.DISCONNECTED, TAG);
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000378 order.verify(mNotificationManager)
379 .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle));
Tony Makde7f7d12016-06-30 11:19:20 +0100380
381 // Notification should be cleared after unsetting always-on package.
382 vpn.setAlwaysOnPackage(null, false);
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000383 order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
Tony Makde7f7d12016-06-30 11:19:20 +0100384 }
385
Robin Lee4d03abc2016-05-09 12:32:27 +0100386 /**
Tony Makde7f7d12016-06-30 11:19:20 +0100387 * Mock some methods of vpn object.
Robin Lee4d03abc2016-05-09 12:32:27 +0100388 */
Robin Leeb8c2a2b2017-03-10 16:17:06 +0000389 private Vpn createVpn(@UserIdInt int userId) {
390 return new Vpn(Looper.myLooper(), mContext, mNetService, userId, mSystemServices);
Tony Makde7f7d12016-06-30 11:19:20 +0100391 }
Robin Lee17e61832016-05-09 13:46:28 +0100392
Tony Makde7f7d12016-06-30 11:19:20 +0100393 private static void assertBlocked(Vpn vpn, int... uids) {
394 for (int uid : uids) {
395 assertTrue("Uid " + uid + " should be blocked", vpn.isBlockingUid(uid));
396 }
397 }
398
399 private static void assertUnblocked(Vpn vpn, int... uids) {
400 for (int uid : uids) {
401 assertFalse("Uid " + uid + " should not be blocked", vpn.isBlockingUid(uid));
Robin Lee17e61832016-05-09 13:46:28 +0100402 }
Robin Lee4d03abc2016-05-09 12:32:27 +0100403 }
404
405 /**
406 * Populate {@link #mUserManager} with a list of fake users.
407 */
408 private void setMockedUsers(UserInfo... users) {
409 final Map<Integer, UserInfo> userMap = new ArrayMap<>();
410 for (UserInfo user : users) {
411 userMap.put(user.id, user);
412 }
413
Robin Lee17e61832016-05-09 13:46:28 +0100414 /**
415 * @see UserManagerService#getUsers(boolean)
416 */
Robin Lee4d03abc2016-05-09 12:32:27 +0100417 doAnswer(invocation -> {
Robin Lee17e61832016-05-09 13:46:28 +0100418 final boolean excludeDying = (boolean) invocation.getArguments()[0];
419 final ArrayList<UserInfo> result = new ArrayList<>(users.length);
420 for (UserInfo ui : users) {
421 if (!excludeDying || (ui.isEnabled() && !ui.partial)) {
422 result.add(ui);
423 }
424 }
425 return result;
426 }).when(mUserManager).getUsers(anyBoolean());
Robin Lee4d03abc2016-05-09 12:32:27 +0100427
428 doAnswer(invocation -> {
429 final int id = (int) invocation.getArguments()[0];
430 return userMap.get(id);
431 }).when(mUserManager).getUserInfo(anyInt());
432
433 doAnswer(invocation -> {
434 final int id = (int) invocation.getArguments()[0];
435 return (userMap.get(id).flags & UserInfo.FLAG_ADMIN) != 0;
436 }).when(mUserManager).canHaveRestrictedProfile(anyInt());
437 }
438
439 /**
440 * Populate {@link #mPackageManager} with a fake packageName-to-UID mapping.
441 */
442 private void setMockedPackages(final Map<String, Integer> packages) {
443 try {
444 doAnswer(invocation -> {
445 final String appName = (String) invocation.getArguments()[0];
446 final int userId = (int) invocation.getArguments()[1];
447 return UserHandle.getUid(userId, packages.get(appName));
448 }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt());
449 } catch (Exception e) {
450 }
451 }
452}