• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package com.android.server.connectivity;
18 
19 import static android.Manifest.permission.CHANGE_NETWORK_STATE;
20 import static android.Manifest.permission.CHANGE_WIFI_STATE;
21 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
22 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
23 import static android.Manifest.permission.INTERNET;
24 import static android.Manifest.permission.NEARBY_WIFI_DEVICES;
25 import static android.Manifest.permission.NETWORK_STACK;
26 import static android.Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS;
27 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
28 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
29 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
30 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
31 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
32 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED;
33 import static android.content.pm.PackageManager.GET_PERMISSIONS;
34 import static android.content.pm.PackageManager.MATCH_ANY_USER;
35 import static android.content.pm.PackageManager.PERMISSION_DENIED;
36 import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS;
37 import static android.net.INetd.PERMISSION_INTERNET;
38 import static android.net.INetd.PERMISSION_NETWORK;
39 import static android.net.INetd.PERMISSION_NONE;
40 import static android.net.INetd.PERMISSION_SYSTEM;
41 import static android.net.INetd.PERMISSION_UNINSTALLED;
42 import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
43 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
44 import static android.net.connectivity.ConnectivityCompatChanges.RESTRICT_LOCAL_NETWORK;
45 import static android.os.Process.SYSTEM_UID;
46 import static android.permission.PermissionManager.PERMISSION_GRANTED;
47 
48 import static com.android.server.connectivity.PermissionMonitor.isHigherNetworkPermission;
49 import static com.android.testutils.TestPermissionUtil.runAsShell;
50 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
51 
52 import static junit.framework.Assert.fail;
53 
54 import static org.junit.Assert.assertEquals;
55 import static org.junit.Assert.assertFalse;
56 import static org.junit.Assert.assertTrue;
57 import static org.junit.Assume.assumeTrue;
58 import static org.mockito.AdditionalMatchers.aryEq;
59 import static org.mockito.ArgumentMatchers.any;
60 import static org.mockito.ArgumentMatchers.anyBoolean;
61 import static org.mockito.ArgumentMatchers.anyInt;
62 import static org.mockito.ArgumentMatchers.anyString;
63 import static org.mockito.ArgumentMatchers.argThat;
64 import static org.mockito.ArgumentMatchers.eq;
65 import static org.mockito.ArgumentMatchers.intThat;
66 import static org.mockito.Mockito.atLeast;
67 import static org.mockito.Mockito.doAnswer;
68 import static org.mockito.Mockito.doCallRealMethod;
69 import static org.mockito.Mockito.doReturn;
70 import static org.mockito.Mockito.mock;
71 import static org.mockito.Mockito.never;
72 import static org.mockito.Mockito.reset;
73 import static org.mockito.Mockito.times;
74 import static org.mockito.Mockito.verify;
75 import static org.mockito.Mockito.when;
76 
77 import android.compat.testing.PlatformCompatChangeRule;
78 import android.content.AttributionSource;
79 import android.content.BroadcastReceiver;
80 import android.content.Context;
81 import android.content.Intent;
82 import android.content.pm.ApplicationInfo;
83 import android.content.pm.PackageInfo;
84 import android.content.pm.PackageManager;
85 import android.database.ContentObserver;
86 import android.net.INetd;
87 import android.net.UidRange;
88 import android.net.Uri;
89 import android.os.Build;
90 import android.os.Handler;
91 import android.os.HandlerThread;
92 import android.os.Process;
93 import android.os.SystemConfigManager;
94 import android.os.UserHandle;
95 import android.os.UserManager;
96 import android.permission.PermissionManager;
97 import android.provider.Settings;
98 import android.util.ArraySet;
99 import android.util.SparseIntArray;
100 
101 import androidx.annotation.NonNull;
102 import androidx.annotation.Nullable;
103 import androidx.test.InstrumentationRegistry;
104 import androidx.test.filters.SmallTest;
105 
106 import com.android.modules.utils.build.SdkLevel;
107 import com.android.net.module.util.CollectionUtils;
108 import com.android.networkstack.apishim.ProcessShimImpl;
109 import com.android.networkstack.apishim.common.ProcessShim;
110 import com.android.server.BpfNetMaps;
111 import com.android.testutils.DevSdkIgnoreRule;
112 import com.android.testutils.DevSdkIgnoreRunner;
113 import com.android.testutils.HandlerUtils;
114 
115 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
116 
117 import org.junit.After;
118 import org.junit.Before;
119 import org.junit.Rule;
120 import org.junit.Test;
121 import org.junit.rules.TestRule;
122 import org.junit.runner.RunWith;
123 import org.mockito.AdditionalAnswers;
124 import org.mockito.ArgumentCaptor;
125 import org.mockito.Mock;
126 import org.mockito.MockitoAnnotations;
127 import org.mockito.invocation.InvocationOnMock;
128 
129 import java.lang.reflect.Array;
130 import java.util.Arrays;
131 import java.util.List;
132 import java.util.Set;
133 
134 @RunWith(DevSdkIgnoreRunner.class)
135 @SmallTest
136 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
137 public class PermissionMonitorTest {
138     @Rule
139     public TestRule compatChangeRule = new PlatformCompatChangeRule();
140     private static final int MOCK_USER_ID1 = 0;
141     private static final int MOCK_USER_ID2 = 1;
142     private static final int MOCK_USER_ID3 = 2;
143     private static final UserHandle MOCK_USER1 = UserHandle.of(MOCK_USER_ID1);
144     private static final UserHandle MOCK_USER2 = UserHandle.of(MOCK_USER_ID2);
145     private static final UserHandle MOCK_USER3 = UserHandle.of(MOCK_USER_ID3);
146     private static final int MOCK_APPID1 = 10001;
147     private static final int MOCK_APPID2 = 10086;
148     private static final int MOCK_APPID3 = 10110;
149     private static final int MOCK_APPID4 = 10111;
150     private static final int SYSTEM_APPID1 = 1100;
151     private static final int SYSTEM_APPID2 = 1108;
152     private static final int VPN_APPID = 10002;
153     private static final int MOCK_UID11 = MOCK_USER1.getUid(MOCK_APPID1);
154     private static final int MOCK_UID12 = MOCK_USER1.getUid(MOCK_APPID2);
155     private static final int MOCK_UID13 = MOCK_USER1.getUid(MOCK_APPID3);
156     private static final int MOCK_UID14 = MOCK_USER1.getUid(MOCK_APPID4);
157     private static final int SYSTEM_APP_UID11 = MOCK_USER1.getUid(SYSTEM_APPID1);
158     private static final int VPN_UID = MOCK_USER1.getUid(VPN_APPID);
159     private static final int MOCK_UID21 = MOCK_USER2.getUid(MOCK_APPID1);
160     private static final int MOCK_UID22 = MOCK_USER2.getUid(MOCK_APPID2);
161     private static final int MOCK_UID23 = MOCK_USER2.getUid(MOCK_APPID3);
162     private static final int SYSTEM_APP_UID21 = MOCK_USER2.getUid(SYSTEM_APPID1);
163     private static final int MOCK_UID31 = MOCK_USER3.getUid(MOCK_APPID1);
164     private static final int MOCK_UID32 = MOCK_USER3.getUid(MOCK_APPID2);
165     private static final int MOCK_UID33 = MOCK_USER3.getUid(MOCK_APPID3);
166     private static final String REAL_SYSTEM_PACKAGE_NAME = "android";
167     private static final String MOCK_PACKAGE1 = "appName1";
168     private static final String MOCK_PACKAGE2 = "appName2";
169     private static final String MOCK_PACKAGE3 = "appName3";
170     private static final String SYSTEM_PACKAGE1 = "sysName1";
171     private static final String SYSTEM_PACKAGE2 = "sysName2";
172     private static final String PARTITION_SYSTEM = "system";
173     private static final String PARTITION_OEM = "oem";
174     private static final String PARTITION_PRODUCT = "product";
175     private static final String PARTITION_VENDOR = "vendor";
176     private static final int VERSION_P = Build.VERSION_CODES.P;
177     private static final int VERSION_Q = Build.VERSION_CODES.Q;
178     private static final int PERMISSION_TRAFFIC_ALL =
179             PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
180     private static final int TIMEOUT_MS = 2_000;
181     // The ACCESS_LOCAL_NETWORK permission is not available yet. For the time being, use
182     // NEARBY_WIFI_DEVICES as a means to develop, for expediency.
183     // TODO(b/375236298): remove this constant when the ACCESS_LOCAL_NETWORK permission is defined.
184     private static final String ACCESS_LOCAL_NETWORK = NEARBY_WIFI_DEVICES;
185 
186     @Mock private Context mContext;
187     @Mock private PackageManager mPackageManager;
188     @Mock private PermissionManager mPermissionManager;
189     @Mock private INetd mNetdService;
190     @Mock private UserManager mUserManager;
191     @Mock private PermissionMonitor.Dependencies mDeps;
192     @Mock private SystemConfigManager mSystemConfigManager;
193     @Mock private BpfNetMaps mBpfNetMaps;
194 
195     private PermissionMonitor mPermissionMonitor;
196     private NetdMonitor mNetdMonitor;
197     private BpfMapMonitor mBpfMapMonitor;
198     private HandlerThread mHandlerThread;
199     private ProcessShim mProcessShim = ProcessShimImpl.newInstance();
200 
201     @Before
setUp()202     public void setUp() throws Exception {
203         MockitoAnnotations.initMocks(this);
204         when(mContext.getPackageManager()).thenReturn(mPackageManager);
205         when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
206         doReturn(List.of(MOCK_USER1)).when(mUserManager).getUserHandles(eq(true));
207         when(mContext.getSystemService(PermissionManager.class)).thenReturn(mPermissionManager);
208         when(mContext.getSystemServiceName(SystemConfigManager.class))
209                 .thenReturn(Context.SYSTEM_CONFIG_SERVICE);
210         when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE))
211                 .thenReturn(mSystemConfigManager);
212         if (mContext.getSystemService(SystemConfigManager.class) == null) {
213             // Test is using mockito-extended
214             doCallRealMethod().when(mContext).getSystemService(SystemConfigManager.class);
215         }
216         when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
217         doAnswer(invocation -> {
218             final Object[] args = invocation.getArguments();
219             final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext));
220             final UserHandle user = (UserHandle) args[0];
221             doReturn(user).when(asUserCtx).getUser();
222             return asUserCtx;
223         }).when(mContext).createContextAsUser(any(), anyInt());
224         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of());
225         // Set DEVICE_INITIAL_SDK_INT to Q that SYSTEM_UID won't have restricted network permission
226         // by default.
227         doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
228 
229         mHandlerThread = new HandlerThread("PermissionMonitorTest");
230         mPermissionMonitor = new PermissionMonitor(
231                 mContext, mNetdService, mBpfNetMaps, mDeps, mHandlerThread);
232         mNetdMonitor = new NetdMonitor(mNetdService);
233         mBpfMapMonitor = new BpfMapMonitor(mBpfNetMaps);
234 
235         // Start the HandlerThread after PermissionMonitor created as CS current behavior.
236         mHandlerThread.start();
237 
238         doReturn(List.of()).when(mPackageManager).getInstalledPackagesAsUser(anyInt(), anyInt());
239         onUserAdded(MOCK_USER1);
240     }
241 
242     @After
tearDown()243     public void tearDown() throws Exception {
244         if (mHandlerThread != null) {
245             mHandlerThread.quitSafely();
246             mHandlerThread.join();
247         }
248     }
249 
hasRestrictedNetworkPermission(String partition, int targetSdkVersion, String packageName, int uid, String... permissions)250     private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion,
251             String packageName, int uid, String... permissions) {
252         final PackageInfo packageInfo =
253                 packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition);
254         packageInfo.packageName = packageName;
255         packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
256         packageInfo.applicationInfo.uid = uid;
257         return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
258     }
259 
hasSdkSandbox(final int uid)260     private boolean hasSdkSandbox(final int uid) {
261         return SdkLevel.isAtLeastT() && Process.isApplicationUid(uid);
262     }
263 
systemPackageInfoWithPermissions(String... permissions)264     private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
265         return packageInfoWithPermissions(
266                 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
267     }
268 
vendorPackageInfoWithPermissions(String... permissions)269     private static PackageInfo vendorPackageInfoWithPermissions(String... permissions) {
270         return packageInfoWithPermissions(
271                 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_VENDOR);
272     }
273 
packageInfoWithPermissions(int permissionsFlags, String[] permissions, String partition)274     private static PackageInfo packageInfoWithPermissions(int permissionsFlags,
275             String[] permissions, String partition) {
276         int[] requestedPermissionsFlags = new int[permissions.length];
277         for (int i = 0; i < permissions.length; i++) {
278             requestedPermissionsFlags[i] = permissionsFlags;
279         }
280         final PackageInfo packageInfo = new PackageInfo();
281         packageInfo.requestedPermissions = permissions;
282         packageInfo.applicationInfo = new ApplicationInfo();
283         packageInfo.requestedPermissionsFlags = requestedPermissionsFlags;
284         int privateFlags = 0;
285         switch (partition) {
286             case PARTITION_OEM:
287                 privateFlags = PRIVATE_FLAG_OEM;
288                 break;
289             case PARTITION_PRODUCT:
290                 privateFlags = PRIVATE_FLAG_PRODUCT;
291                 break;
292             case PARTITION_VENDOR:
293                 privateFlags = PRIVATE_FLAG_VENDOR;
294                 break;
295         }
296         packageInfo.applicationInfo.privateFlags = privateFlags;
297         return packageInfo;
298     }
299 
buildPackageInfo(String packageName, int uid, String... permissions)300     private static PackageInfo buildPackageInfo(String packageName, int uid,
301             String... permissions) {
302         final PackageInfo pkgInfo = systemPackageInfoWithPermissions(permissions);
303         pkgInfo.packageName = packageName;
304         pkgInfo.applicationInfo.uid = uid;
305         return pkgInfo;
306     }
307 
308     // TODO: Move this method to static lib.
appendElement(Class<T> kind, @Nullable T[] array, T element)309     private static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element) {
310         final T[] result;
311         if (array != null) {
312             result = Arrays.copyOf(array, array.length + 1);
313         } else {
314             result = (T[]) Array.newInstance(kind, 1);
315         }
316         result[result.length - 1] = element;
317         return result;
318     }
319 
buildAndMockPackageInfoWithPermissions(String packageName, int uid, String... permissions)320     private PackageInfo buildAndMockPackageInfoWithPermissions(String packageName, int uid,
321             String... permissions) throws Exception {
322         final PackageInfo packageInfo = buildPackageInfo(packageName, uid, permissions);
323         // This will return the wrong UID for the package when queried with other users.
324         doReturn(packageInfo).when(mPackageManager)
325                 .getPackageInfo(eq(packageName), anyInt() /* flag */);
326         if (BpfNetMaps.isAtLeast25Q2()) {
327             // Runtime permission checks for local net restrictions were introduced in 25Q2
328             for (String permission : permissions) {
329                 doReturn(PERMISSION_GRANTED).when(mPermissionManager).checkPermissionForPreflight(
330                         eq(permission),
331                         argThat(attributionSource -> attributionSource.getUid() == uid));
332             }
333         }
334         final String[] oldPackages = mPackageManager.getPackagesForUid(uid);
335         // If it's duplicated package, no need to set it again.
336         if (CollectionUtils.contains(oldPackages, packageName)) return packageInfo;
337 
338         // Combine the package if this uid is shared with other packages.
339         final String[] newPackages = appendElement(String.class, oldPackages, packageName);
340         doReturn(newPackages).when(mPackageManager).getPackagesForUid(eq(uid));
341         return packageInfo;
342     }
343 
startMonitoring()344     private void startMonitoring() {
345         processOnHandlerThread(() -> mPermissionMonitor.startMonitoring());
346     }
347 
onUserAdded(UserHandle user)348     private void onUserAdded(UserHandle user) {
349         processOnHandlerThread(() -> mPermissionMonitor.onUserAdded(user));
350     }
351 
onUserRemoved(UserHandle user)352     private void onUserRemoved(UserHandle user) {
353         processOnHandlerThread(() -> mPermissionMonitor.onUserRemoved(user));
354     }
355 
onPackageAdded(String packageName, int uid)356     private void onPackageAdded(String packageName, int uid) {
357         processOnHandlerThread(() -> mPermissionMonitor.onPackageAdded(packageName, uid));
358     }
359 
onPackageRemoved(String packageName, int uid)360     private void onPackageRemoved(String packageName, int uid) {
361         processOnHandlerThread(() -> mPermissionMonitor.onPackageRemoved(packageName, uid));
362     }
363 
sendAppIdsTrafficPermission(SparseIntArray netdPermissionsAppIds)364     private void sendAppIdsTrafficPermission(SparseIntArray netdPermissionsAppIds) {
365         processOnHandlerThread(() ->
366                 mPermissionMonitor.sendAppIdsTrafficPermission(netdPermissionsAppIds));
367     }
368 
sendPackagePermissionsForAppId(int appId, int permissions)369     private void sendPackagePermissionsForAppId(int appId, int permissions) {
370         processOnHandlerThread(() ->
371                 mPermissionMonitor.sendPackagePermissionsForAppId(appId, permissions));
372     }
373 
addPackage(String packageName, int uid, String... permissions)374     private void addPackage(String packageName, int uid, String... permissions) throws Exception {
375         buildAndMockPackageInfoWithPermissions(packageName, uid, permissions);
376         onPackageAdded(packageName, uid);
377     }
378 
removePackage(String packageName, int uid)379     private void removePackage(String packageName, int uid) {
380         final String[] oldPackages = mPackageManager.getPackagesForUid(uid);
381         // If the package isn't existed, no need to remove it.
382         if (!CollectionUtils.contains(oldPackages, packageName)) return;
383 
384         // Remove the package if this uid is shared with other packages.
385         final String[] newPackages = Arrays.stream(oldPackages).filter(e -> !e.equals(packageName))
386                 .toArray(String[]::new);
387         doReturn(newPackages).when(mPackageManager).getPackagesForUid(eq(uid));
388         if (BpfNetMaps.isAtLeast25Q2()){
389             // Runtime permission checks for local net restrictions were introduced in 25Q2
390             doReturn(PERMISSION_DENIED).when(mPermissionManager).checkPermissionForPreflight(
391                     anyString(), argThat(as -> as.getUid() == uid));
392         }
393         onPackageRemoved(packageName, uid);
394     }
395 
396     @Test
testHasPermission()397     public void testHasPermission() {
398         PackageInfo app = systemPackageInfoWithPermissions();
399         assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
400         assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
401         assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
402         assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
403 
404         app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE, NETWORK_STACK);
405         assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
406         assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
407         assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
408         assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
409 
410         app = systemPackageInfoWithPermissions(
411                 CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
412         assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
413         assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
414         assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
415         assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
416 
417         app = packageInfoWithPermissions(REQUESTED_PERMISSION_REQUIRED, new String[] {
418                 CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL, NETWORK_STACK },
419                 PARTITION_SYSTEM);
420         assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
421         assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
422         assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
423         assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
424 
425         app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
426         app.requestedPermissions = null;
427         assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
428 
429         app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
430         app.requestedPermissionsFlags = null;
431         assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
432     }
433 
434     @Test
testIsVendorApp()435     public void testIsVendorApp() {
436         PackageInfo app = systemPackageInfoWithPermissions();
437         assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
438         app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
439                 new String[] {}, PARTITION_OEM);
440         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
441         app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
442                 new String[] {}, PARTITION_PRODUCT);
443         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
444         app = vendorPackageInfoWithPermissions();
445         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
446     }
447 
448     @Test
testHasNetworkPermission()449     public void testHasNetworkPermission() {
450         PackageInfo app = systemPackageInfoWithPermissions();
451         assertFalse(mPermissionMonitor.hasNetworkPermission(app));
452         app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
453         assertTrue(mPermissionMonitor.hasNetworkPermission(app));
454         app = systemPackageInfoWithPermissions(NETWORK_STACK);
455         assertFalse(mPermissionMonitor.hasNetworkPermission(app));
456         app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS);
457         assertFalse(mPermissionMonitor.hasNetworkPermission(app));
458         app = systemPackageInfoWithPermissions(CONNECTIVITY_INTERNAL);
459         assertFalse(mPermissionMonitor.hasNetworkPermission(app));
460     }
461 
462     @Test
testHasRestrictedNetworkPermission()463     public void testHasRestrictedNetworkPermission() {
464         assertFalse(hasRestrictedNetworkPermission(
465                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11));
466         assertFalse(hasRestrictedNetworkPermission(
467                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE));
468         assertTrue(hasRestrictedNetworkPermission(
469                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, NETWORK_STACK));
470         assertFalse(hasRestrictedNetworkPermission(
471                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL));
472         assertTrue(hasRestrictedNetworkPermission(
473                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11,
474                 CONNECTIVITY_USE_RESTRICTED_NETWORKS));
475         assertFalse(hasRestrictedNetworkPermission(
476                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_WIFI_STATE));
477         assertTrue(hasRestrictedNetworkPermission(
478                 PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11,
479                 PERMISSION_MAINLINE_NETWORK_STACK));
480 
481         assertFalse(hasRestrictedNetworkPermission(
482                 PARTITION_SYSTEM, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11));
483         assertFalse(hasRestrictedNetworkPermission(
484                 PARTITION_SYSTEM, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL));
485     }
486 
487     @Test
testHasRestrictedNetworkPermissionSystemUid()488     public void testHasRestrictedNetworkPermissionSystemUid() {
489         doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
490         assertTrue(hasRestrictedNetworkPermission(
491                 PARTITION_SYSTEM, VERSION_P, SYSTEM_PACKAGE1, SYSTEM_UID));
492         assertTrue(hasRestrictedNetworkPermission(
493                 PARTITION_SYSTEM, VERSION_P, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL));
494         assertTrue(hasRestrictedNetworkPermission(
495                 PARTITION_SYSTEM, VERSION_P, SYSTEM_PACKAGE1, SYSTEM_UID,
496                 CONNECTIVITY_USE_RESTRICTED_NETWORKS));
497 
498         doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
499         assertFalse(hasRestrictedNetworkPermission(
500                 PARTITION_SYSTEM, VERSION_Q, SYSTEM_PACKAGE1, SYSTEM_UID));
501         assertFalse(hasRestrictedNetworkPermission(
502                 PARTITION_SYSTEM, VERSION_Q, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL));
503         assertTrue(hasRestrictedNetworkPermission(
504                 PARTITION_SYSTEM, VERSION_Q, SYSTEM_PACKAGE1, SYSTEM_UID,
505                 CONNECTIVITY_USE_RESTRICTED_NETWORKS));
506     }
507 
508     @Test
testHasRestrictedNetworkPermissionVendorApp()509     public void testHasRestrictedNetworkPermissionVendorApp() {
510         assertTrue(hasRestrictedNetworkPermission(
511                 PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11));
512         assertTrue(hasRestrictedNetworkPermission(
513                 PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE));
514         assertTrue(hasRestrictedNetworkPermission(
515                 PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, NETWORK_STACK));
516         assertTrue(hasRestrictedNetworkPermission(
517                 PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL));
518         assertTrue(hasRestrictedNetworkPermission(
519                 PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11,
520                 CONNECTIVITY_USE_RESTRICTED_NETWORKS));
521         assertTrue(hasRestrictedNetworkPermission(
522                 PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_WIFI_STATE));
523 
524         assertFalse(hasRestrictedNetworkPermission(
525                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11));
526         assertFalse(hasRestrictedNetworkPermission(
527                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL));
528         assertFalse(hasRestrictedNetworkPermission(
529                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE));
530     }
531 
532     @Test
testHasRestrictedNetworkPermissionUidAllowedOnRestrictedNetworks()533     public void testHasRestrictedNetworkPermissionUidAllowedOnRestrictedNetworks() {
534         mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID11));
535         assertTrue(hasRestrictedNetworkPermission(
536                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11));
537         assertTrue(hasRestrictedNetworkPermission(
538                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE));
539         assertTrue(hasRestrictedNetworkPermission(
540                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL));
541 
542         assertFalse(hasRestrictedNetworkPermission(
543                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID12));
544         assertFalse(hasRestrictedNetworkPermission(
545                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID12, CHANGE_NETWORK_STATE));
546         assertFalse(hasRestrictedNetworkPermission(
547                 PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID12, CONNECTIVITY_INTERNAL));
548 
549     }
550 
wouldBeCarryoverPackage(String partition, int targetSdkVersion, int uid)551     private boolean wouldBeCarryoverPackage(String partition, int targetSdkVersion, int uid) {
552         final PackageInfo packageInfo = packageInfoWithPermissions(
553                 REQUESTED_PERMISSION_GRANTED, new String[] {}, partition);
554         packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
555         packageInfo.applicationInfo.uid = uid;
556         return mPermissionMonitor.isCarryoverPackage(packageInfo.applicationInfo);
557     }
558 
559     @Test
testIsCarryoverPackage()560     public void testIsCarryoverPackage() {
561         doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
562         assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
563         assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
564         assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID11));
565         assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID11));
566         assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
567         assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
568         assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID11));
569         assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID11));
570 
571         doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
572         assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
573         assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
574         assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID11));
575         assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID11));
576         assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
577         assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
578         assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID11));
579         assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID11));
580 
581         assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, SYSTEM_UID));
582         assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, SYSTEM_UID));
583         assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, MOCK_UID11));
584         assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID11));
585     }
586 
wouldBeUidAllowedOnRestrictedNetworks(int uid)587     private boolean wouldBeUidAllowedOnRestrictedNetworks(int uid) {
588         final ApplicationInfo applicationInfo = new ApplicationInfo();
589         applicationInfo.uid = uid;
590         return mPermissionMonitor.isUidAllowedOnRestrictedNetworks(applicationInfo);
591     }
592 
593     @Test
testIsAppAllowedOnRestrictedNetworks()594     public void testIsAppAllowedOnRestrictedNetworks() {
595         mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of());
596         assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11));
597         assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12));
598 
599         mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID11));
600         assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11));
601         assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12));
602 
603         mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID12));
604         assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11));
605         assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12));
606 
607         mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(123));
608         assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11));
609         assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12));
610     }
611 
assertBackgroundPermission(boolean hasPermission, String name, int uid, String... permissions)612     private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
613             String... permissions) throws Exception {
614         addPackage(name, uid, permissions);
615         assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
616         if (hasSdkSandbox(uid)) {
617             final int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
618             assertEquals(hasPermission,
619                     mPermissionMonitor.hasUseBackgroundNetworksPermission(sdkSandboxUid));
620         }
621     }
622 
623     @Test
624     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testHasUseBackgroundNetworksPermission()625     public void testHasUseBackgroundNetworksPermission() throws Exception {
626         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
627         assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID);
628         assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL);
629         assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE);
630         assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK);
631 
632         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID11));
633         assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID11);
634         assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID11,
635                 CONNECTIVITY_USE_RESTRICTED_NETWORKS);
636 
637         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID12));
638         assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID12);
639         assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID12,
640                 CONNECTIVITY_INTERNAL);
641         assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID12, NETWORK_STACK);
642     }
643 
644     private class BpfMapMonitor {
645         private final SparseIntArray mAppIdsTrafficPermission = new SparseIntArray();
646         private final ArraySet<Integer> mLocalNetBlockedUids = new ArraySet<>();
647         private static final int DOES_NOT_EXIST = -2;
648 
BpfMapMonitor(BpfNetMaps mockBpfmap)649         BpfMapMonitor(BpfNetMaps mockBpfmap) throws Exception {
650             // Add hook to verify and track result of trafficSetNetPerm.
651             doAnswer((InvocationOnMock invocation) -> {
652                 final Object[] args = invocation.getArguments();
653                 final int permission = (int) args[0];
654                 for (final int appId : (int[]) args[1]) {
655                     mAppIdsTrafficPermission.put(appId, permission);
656                 }
657                 return null;
658             }).when(mockBpfmap).setNetPermForUids(anyInt(), any(int[].class));
659             doAnswer((InvocationOnMock invocation) -> {
660                 final Object[] args = invocation.getArguments();
661                 final int uid = (int) args[0];
662                 mLocalNetBlockedUids.add(uid);
663                 return null;
664             }).when(mockBpfmap).addUidToLocalNetBlockMap(anyInt());
665             doAnswer((InvocationOnMock invocation) -> {
666                 final Object[] args = invocation.getArguments();
667                 final int uid = (int) args[0];
668                 mLocalNetBlockedUids.remove(uid);
669                 return null;
670             }).when(mockBpfmap).removeUidFromLocalNetBlockMap(anyInt());
671         }
672 
expectTrafficPerm(int permission, Integer... appIds)673         public void expectTrafficPerm(int permission, Integer... appIds) {
674             for (final int appId : appIds) {
675                 if (mAppIdsTrafficPermission.get(appId, DOES_NOT_EXIST) == DOES_NOT_EXIST) {
676                     fail("appId " + appId + " does not exist.");
677                 }
678                 if (mAppIdsTrafficPermission.get(appId) != permission) {
679                     fail("appId " + appId + " has wrong permission: "
680                             + mAppIdsTrafficPermission.get(appId));
681                 }
682                 if (hasSdkSandbox(appId)) {
683                     int sdkSandboxAppId = mProcessShim.toSdkSandboxUid(appId);
684                     if (mAppIdsTrafficPermission.get(sdkSandboxAppId, DOES_NOT_EXIST)
685                             == DOES_NOT_EXIST) {
686                         fail("SDK sandbox appId " + sdkSandboxAppId + " does not exist.");
687                     }
688                     if (mAppIdsTrafficPermission.get(sdkSandboxAppId) != permission) {
689                         fail("SDK sandbox appId " + sdkSandboxAppId + " has wrong permission: "
690                                 + mAppIdsTrafficPermission.get(sdkSandboxAppId));
691                     }
692                 }
693             }
694         }
695 
hasLocalNetPermissions(int uid)696         public boolean hasLocalNetPermissions(int uid) {
697             return !mLocalNetBlockedUids.contains(uid);
698         }
699 
isUidPresentInLocalNetBlockMap(int uid)700         public boolean isUidPresentInLocalNetBlockMap(int uid) {
701             return mLocalNetBlockedUids.contains(uid);
702         }
703 
hasBlockedLocalNetForSandboxUid(int sandboxUid)704         public boolean hasBlockedLocalNetForSandboxUid(int sandboxUid) {
705             return mLocalNetBlockedUids.contains(sandboxUid);
706         }
707     }
708 
709     private class NetdMonitor {
710         private final SparseIntArray mUidsNetworkPermission = new SparseIntArray();
711         private static final int DOES_NOT_EXIST = -2;
712 
NetdMonitor(INetd mockNetd)713         NetdMonitor(INetd mockNetd) throws Exception {
714             // Add hook to verify and track result of networkSetPermission.
715             doAnswer((InvocationOnMock invocation) -> {
716                 final Object[] args = invocation.getArguments();
717                 final int permission = (int) args[0];
718                 for (final int uid : (int[]) args[1]) {
719                     // TODO: Currently, permission monitor will send duplicate commands for each uid
720                     // corresponding to each user. Need to fix that and uncomment below test.
721                     // if (mApps.containsKey(uid) && mApps.get(uid) == isSystem) {
722                     //     fail("uid " + uid + " is already set to " + isSystem);
723                     // }
724                     mUidsNetworkPermission.put(uid, permission);
725                 }
726                 return null;
727             }).when(mockNetd).networkSetPermissionForUser(anyInt(), any(int[].class));
728 
729             // Add hook to verify and track result of networkClearPermission.
730             doAnswer((InvocationOnMock invocation) -> {
731                 final Object[] args = invocation.getArguments();
732                 for (final int uid : (int[]) args[0]) {
733                     // TODO: Currently, permission monitor will send duplicate commands for each uid
734                     // corresponding to each user. Need to fix that and uncomment below test.
735                     // if (!mApps.containsKey(uid)) {
736                     //     fail("uid " + uid + " does not exist.");
737                     // }
738                     mUidsNetworkPermission.delete(uid);
739                 }
740                 return null;
741             }).when(mockNetd).networkClearPermissionForUser(any(int[].class));
742         }
743 
expectNetworkPerm(int permission, UserHandle[] users, int... appIds)744         public void expectNetworkPerm(int permission, UserHandle[] users, int... appIds) {
745             for (final UserHandle user : users) {
746                 for (final int appId : appIds) {
747                     final int uid = user.getUid(appId);
748                     if (mUidsNetworkPermission.get(uid, DOES_NOT_EXIST) == DOES_NOT_EXIST) {
749                         fail("uid " + uid + " does not exist.");
750                     }
751                     if (mUidsNetworkPermission.get(uid) != permission) {
752                         fail("uid " + uid + " has wrong permission: " +  permission);
753                     }
754                     if (hasSdkSandbox(uid)) {
755                         int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
756                         if (mUidsNetworkPermission.get(sdkSandboxUid, DOES_NOT_EXIST)
757                                 == DOES_NOT_EXIST) {
758                             fail("SDK sandbox uid " + uid + " does not exist.");
759                         }
760                         if (mUidsNetworkPermission.get(sdkSandboxUid) != permission) {
761                             fail("SDK sandbox uid " + uid + " has wrong permission: "
762                                     + permission);
763                         }
764                     }
765                 }
766             }
767         }
768 
expectNoNetworkPerm(UserHandle[] users, int... appIds)769         public void expectNoNetworkPerm(UserHandle[] users, int... appIds) {
770             for (final UserHandle user : users) {
771                 for (final int appId : appIds) {
772                     final int uid = user.getUid(appId);
773                     if (mUidsNetworkPermission.get(uid, DOES_NOT_EXIST) != DOES_NOT_EXIST) {
774                         fail("uid " + uid + " has listed permissions, expected none.");
775                     }
776                     if (hasSdkSandbox(uid)) {
777                         int sdkSandboxUid = mProcessShim.toSdkSandboxUid(uid);
778                         if (mUidsNetworkPermission.get(sdkSandboxUid, DOES_NOT_EXIST)
779                                 != DOES_NOT_EXIST) {
780                             fail("SDK sandbox uid " + sdkSandboxUid
781                                     + " has listed permissions, expected none.");
782                         }
783                     }
784                 }
785             }
786         }
787     }
788 
789     @Test
790     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testUserAndPackageAddRemove()791     public void testUserAndPackageAddRemove() throws Exception {
792         // MOCK_UID11: MOCK_PACKAGE1 only has network permission.
793         // SYSTEM_APP_UID11: SYSTEM_PACKAGE1 has system permission.
794         // SYSTEM_APP_UID11: SYSTEM_PACKAGE2 only has network permission.
795         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE);
796         buildAndMockPackageInfoWithPermissions(SYSTEM_PACKAGE1, SYSTEM_APP_UID11,
797                 CONNECTIVITY_USE_RESTRICTED_NETWORKS);
798         buildAndMockPackageInfoWithPermissions(SYSTEM_PACKAGE2, SYSTEM_APP_UID11,
799                 CHANGE_NETWORK_STATE);
800 
801         // Add user MOCK_USER1.
802         onUserAdded(MOCK_USER1);
803         // Add SYSTEM_PACKAGE2, expect only have network permission.
804         addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_APPID1);
805         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
806                 SYSTEM_APPID1);
807 
808         // Add SYSTEM_PACKAGE1, expect permission upgrade.
809         addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_APPID1);
810         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
811                 SYSTEM_APPID1);
812 
813         final List<PackageInfo> pkgs = List.of(
814                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID21,
815                         CONNECTIVITY_USE_RESTRICTED_NETWORKS),
816                 buildPackageInfo(SYSTEM_PACKAGE2, SYSTEM_APP_UID21, CHANGE_NETWORK_STATE));
817         doReturn(pkgs).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
818                 eq(MOCK_USER_ID2));
819         // Add user MOCK_USER2.
820         onUserAdded(MOCK_USER2);
821         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
822                 SYSTEM_APPID1);
823 
824         // Remove SYSTEM_PACKAGE2, expect keep system permission.
825         doReturn(new String[]{SYSTEM_PACKAGE1}).when(mPackageManager)
826                 .getPackagesForUid(intThat(uid -> UserHandle.getAppId(uid) == SYSTEM_APPID1));
827         removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2},
828                 SYSTEM_PACKAGE2, SYSTEM_APPID1);
829         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
830                 SYSTEM_APPID1);
831 
832         // Add SYSTEM_PACKAGE2, expect keep system permission.
833         addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_PACKAGE2,
834                 SYSTEM_APPID1);
835         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
836                 SYSTEM_APPID1);
837 
838         // Add MOCK_PACKAGE1
839         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID21, CHANGE_NETWORK_STATE);
840         addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1);
841         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
842                 SYSTEM_APPID1);
843         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
844                 MOCK_APPID1);
845 
846         // Remove MOCK_PACKAGE1, expect no permission left for all user.
847         doReturn(new String[]{}).when(mPackageManager)
848                 .getPackagesForUid(intThat(uid -> UserHandle.getAppId(uid) == MOCK_APPID1));
849         removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1);
850         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_APPID1);
851 
852         // Remove SYSTEM_PACKAGE1, expect permission downgrade.
853         when(mPackageManager.getPackagesForUid(
854                 intThat(uid -> UserHandle.getAppId(uid) == SYSTEM_APPID1)))
855                 .thenReturn(new String[]{SYSTEM_PACKAGE2});
856         removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2},
857                 SYSTEM_PACKAGE1, SYSTEM_APPID1);
858         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
859                 SYSTEM_APPID1);
860 
861         onUserRemoved(MOCK_USER1);
862         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER2},
863                 SYSTEM_APPID1);
864         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, SYSTEM_APPID1);
865 
866         // Remove all packages, expect no permission left.
867         when(mPackageManager.getPackagesForUid(
868                 intThat(uid -> UserHandle.getAppId(uid) == SYSTEM_APPID1)))
869                 .thenReturn(new String[]{});
870         removePackageForUsers(new UserHandle[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_APPID1);
871         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_APPID1,
872                 MOCK_APPID1);
873 
874         // Remove last user, expect no permission change.
875         onUserRemoved(MOCK_USER2);
876         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_APPID1,
877                 MOCK_APPID1);
878     }
879 
880     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
881     @Test
882     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLocalNetRestrictions_onUserAdded()883     public void testLocalNetRestrictions_onUserAdded() throws Exception {
884         assumeTrue(BpfNetMaps.isAtLeast25Q2());
885         doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt());
886         when(mPermissionManager.checkPermissionForPreflight(
887                 anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED);
888         final PackageInfo packageInfo = buildAndMockPackageInfoWithPermissions(
889                 MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE);
890         // Set package for all users on devices
891         doReturn(List.of(packageInfo)).when(mPackageManager)
892                 .getInstalledPackagesAsUser(anyInt(), eq(MOCK_USER1.getIdentifier()));
893         onUserAdded(MOCK_USER1);
894 
895         assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
896         if (hasSdkSandbox(MOCK_UID11)) {
897             assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid(
898                     mProcessShim.toSdkSandboxUid(MOCK_UID11)));
899         }
900     }
901 
902     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
903     @Test
904     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLocalNetRestrictions_onUserRemoved()905     public void testLocalNetRestrictions_onUserRemoved() throws Exception {
906         assumeTrue(BpfNetMaps.isAtLeast25Q2());
907         doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt());
908         when(mPermissionManager.checkPermissionForPreflight(
909                 anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED);
910         final PackageInfo packageInfo = buildAndMockPackageInfoWithPermissions(
911                 MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE);
912         // Set package for all users on devices
913         doReturn(List.of(packageInfo)).when(mPackageManager)
914                 .getInstalledPackagesAsUser(anyInt(), eq(MOCK_USER1.getIdentifier()));
915         onUserAdded(MOCK_USER1);
916         assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
917 
918         onUserRemoved(MOCK_USER1);
919         assertFalse(mBpfMapMonitor.isUidPresentInLocalNetBlockMap(MOCK_UID11));
920     }
921 
doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates(@ullable String ifName)922     private void doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates(@Nullable String ifName)
923             throws Exception {
924         doReturn(List.of(
925                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
926                         CONNECTIVITY_USE_RESTRICTED_NETWORKS),
927                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
928                 buildPackageInfo(MOCK_PACKAGE2, MOCK_UID12),
929                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
930                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
931         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11);
932         startMonitoring();
933         // Every app on user 0 except MOCK_UID12 is subject to the VPN.
934         final Set<UidRange> vpnRange1 = Set.of(
935                 new UidRange(0, MOCK_UID12 - 1),
936                 new UidRange(MOCK_UID12 + 1, UserHandle.PER_USER_RANGE - 1));
937         final Set<UidRange> vpnRange2 = Set.of(new UidRange(MOCK_UID12, MOCK_UID12));
938 
939         // When VPN is connected, expect a rule to be set up for user app MOCK_UID11
940         mPermissionMonitor.onVpnUidRangesAdded(ifName, vpnRange1, VPN_UID);
941         verify(mBpfNetMaps).addUidInterfaceRules(eq(ifName), aryEq(new int[]{MOCK_UID11}));
942 
943         reset(mBpfNetMaps);
944 
945         // When MOCK_UID11 package is uninstalled and reinstalled, expect Netd to be updated
946         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
947         verify(mBpfNetMaps).removeUidInterfaceRules(aryEq(new int[]{MOCK_UID11}));
948         onPackageAdded(MOCK_PACKAGE1, MOCK_UID11);
949         verify(mBpfNetMaps).addUidInterfaceRules(eq(ifName), aryEq(new int[]{MOCK_UID11}));
950 
951         reset(mBpfNetMaps);
952 
953         // During VPN uid update (vpnRange1 -> vpnRange2), ConnectivityService first deletes the
954         // old UID rules then adds the new ones. Expect netd to be updated
955         mPermissionMonitor.onVpnUidRangesRemoved(ifName, vpnRange1, VPN_UID);
956         verify(mBpfNetMaps).removeUidInterfaceRules(aryEq(new int[] {MOCK_UID11}));
957         mPermissionMonitor.onVpnUidRangesAdded(ifName, vpnRange2, VPN_UID);
958         verify(mBpfNetMaps).addUidInterfaceRules(eq(ifName), aryEq(new int[]{MOCK_UID12}));
959 
960         reset(mBpfNetMaps);
961 
962         // When VPN is disconnected, expect rules to be torn down
963         mPermissionMonitor.onVpnUidRangesRemoved(ifName, vpnRange2, VPN_UID);
964         verify(mBpfNetMaps).removeUidInterfaceRules(aryEq(new int[] {MOCK_UID12}));
965     }
966 
967     @Test
968     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testUidFilteringDuringVpnConnectDisconnectAndUidUpdates()969     public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
970         doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates("tun0");
971     }
972 
973     @Test
974     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testUidFilteringDuringVpnConnectDisconnectAndUidUpdatesWithWildcard()975     public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdatesWithWildcard()
976             throws Exception {
977         doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates(null /* ifName */);
978     }
979 
doTestUidFilteringDuringPackageInstallAndUninstall(@ullable String ifName)980     private void doTestUidFilteringDuringPackageInstallAndUninstall(@Nullable String ifName) throws
981             Exception {
982         doReturn(List.of(
983                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
984                         NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS),
985                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
986                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
987         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11);
988         doReturn(List.of(MOCK_USER1, MOCK_USER2)).when(mUserManager).getUserHandles(eq(true));
989 
990         startMonitoring();
991         final Set<UidRange> vpnRange = Set.of(UidRange.createForUser(MOCK_USER1),
992                 UidRange.createForUser(MOCK_USER2));
993         mPermissionMonitor.onVpnUidRangesAdded(ifName, vpnRange, VPN_UID);
994 
995         // Newly-installed package should have uid rules added
996         addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1);
997         verify(mBpfNetMaps).addUidInterfaceRules(eq(ifName), aryEq(new int[]{MOCK_UID11}));
998         verify(mBpfNetMaps).addUidInterfaceRules(eq(ifName), aryEq(new int[]{MOCK_UID21}));
999 
1000         // Removed package should have its uid rules removed
1001         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
1002         verify(mBpfNetMaps).removeUidInterfaceRules(aryEq(new int[]{MOCK_UID11}));
1003         verify(mBpfNetMaps, never()).removeUidInterfaceRules(aryEq(new int[]{MOCK_UID21}));
1004     }
1005 
1006     @Test
1007     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testUidFilteringDuringPackageInstallAndUninstall()1008     public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
1009         doTestUidFilteringDuringPackageInstallAndUninstall("tun0");
1010     }
1011 
1012     @Test
1013     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testUidFilteringDuringPackageInstallAndUninstallWithWildcard()1014     public void testUidFilteringDuringPackageInstallAndUninstallWithWildcard() throws Exception {
1015         doTestUidFilteringDuringPackageInstallAndUninstall(null /* ifName */);
1016     }
1017 
1018     @Test
1019     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLockdownUidFilteringWithLockdownEnableDisable()1020     public void testLockdownUidFilteringWithLockdownEnableDisable() {
1021         doReturn(List.of(
1022                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
1023                         CONNECTIVITY_USE_RESTRICTED_NETWORKS),
1024                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
1025                 buildPackageInfo(MOCK_PACKAGE2, MOCK_UID12),
1026                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
1027                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1028         startMonitoring();
1029         // Every app on user 0 except MOCK_UID12 is subject to the VPN.
1030         final UidRange[] lockdownRange = {
1031                 new UidRange(0, MOCK_UID12 - 1),
1032                 new UidRange(MOCK_UID12 + 1, UserHandle.PER_USER_RANGE - 1)
1033         };
1034 
1035         // Add Lockdown uid range, expect a rule to be set up for MOCK_UID11 and VPN_UID
1036         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange);
1037         verify(mBpfNetMaps, times(2)).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1038         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, true /* add */);
1039         verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, true /* add */);
1040 
1041         reset(mBpfNetMaps);
1042 
1043         // Remove Lockdown uid range, expect rules to be torn down
1044         mPermissionMonitor.updateVpnLockdownUidRanges(false /* add */, lockdownRange);
1045         verify(mBpfNetMaps, times(2)).updateUidLockdownRule(anyInt(), eq(false) /* add */);
1046         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, false /* add */);
1047         verify(mBpfNetMaps).updateUidLockdownRule(VPN_UID, false /* add */);
1048     }
1049 
1050     @Test
1051     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLockdownUidFilteringWithLockdownEnableDisableWithMultiAdd()1052     public void testLockdownUidFilteringWithLockdownEnableDisableWithMultiAdd() {
1053         doReturn(List.of(
1054                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
1055                         CONNECTIVITY_USE_RESTRICTED_NETWORKS),
1056                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
1057                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
1058                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1059         startMonitoring();
1060         // MOCK_UID11 is subject to the VPN.
1061         final UidRange range = new UidRange(MOCK_UID11, MOCK_UID11);
1062         final UidRange[] lockdownRange = {range};
1063 
1064         // Add Lockdown uid range at 1st time, expect a rule to be set up
1065         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange);
1066         verify(mBpfNetMaps).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1067         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, true /* add */);
1068 
1069         reset(mBpfNetMaps);
1070 
1071         // Add Lockdown uid range at 2nd time, expect a rule not to be set up because the uid
1072         // already has the rule
1073         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange);
1074         verify(mBpfNetMaps, never()).updateUidLockdownRule(anyInt(),  anyBoolean());
1075 
1076         reset(mBpfNetMaps);
1077 
1078         // Remove Lockdown uid range at 1st time, expect a rule not to be torn down because we added
1079         // the range 2 times.
1080         mPermissionMonitor.updateVpnLockdownUidRanges(false /* add */, lockdownRange);
1081         verify(mBpfNetMaps, never()).updateUidLockdownRule(anyInt(),  anyBoolean());
1082 
1083         reset(mBpfNetMaps);
1084 
1085         // Remove Lockdown uid range at 2nd time, expect a rule to be torn down because we added
1086         // twice and we removed twice.
1087         mPermissionMonitor.updateVpnLockdownUidRanges(false /* add */, lockdownRange);
1088         verify(mBpfNetMaps).updateUidLockdownRule(anyInt(), eq(false) /* add */);
1089         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, false /* add */);
1090     }
1091 
1092     @Test
1093     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLockdownUidFilteringWithLockdownEnableDisableWithMultiAddAndOverlap()1094     public void testLockdownUidFilteringWithLockdownEnableDisableWithMultiAddAndOverlap() {
1095         doReturn(List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
1096                         CONNECTIVITY_USE_RESTRICTED_NETWORKS),
1097                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID13),
1098                 buildPackageInfo(MOCK_PACKAGE2, MOCK_UID14),
1099                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
1100                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1101         startMonitoring();
1102         // MOCK_UID13 is subject to the VPN.
1103         final UidRange range1 = new UidRange(MOCK_UID13, MOCK_UID13);
1104         final UidRange[] lockdownRange1 = {range1};
1105 
1106         // Add Lockdown uid range at 1st time, expect a rule to be set up
1107         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange1);
1108         verify(mBpfNetMaps).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1109         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID13, true /* add */);
1110 
1111         reset(mBpfNetMaps);
1112 
1113         // MOCK_UID13 and MOCK_UID14 are sequential and subject to the VPN in a separate range.
1114         final UidRange range2 = new UidRange(MOCK_UID13, MOCK_UID14);
1115         final UidRange[] lockdownRange2 = {range2};
1116 
1117         // Add overlapping multiple-UID range. Rule may be set again, which is functionally
1118         // a no-op, so it is fine.
1119         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange2);
1120         verify(mBpfNetMaps, atLeast(1)).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1121         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID14, true /* add */);
1122 
1123         reset(mBpfNetMaps);
1124 
1125         // Remove the multiple-UID range. UID from first rule should not be removed.
1126         mPermissionMonitor.updateVpnLockdownUidRanges(false /* false */, lockdownRange2);
1127         verify(mBpfNetMaps, times(1)).updateUidLockdownRule(anyInt(), eq(false) /* add */);
1128         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID14, false /* add */);
1129 
1130         reset(mBpfNetMaps);
1131 
1132         // Add the multiple-UID range back again to be able to test removing the first range, too.
1133         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange2);
1134         verify(mBpfNetMaps, atLeast(1)).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1135         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID14, true /* add */);
1136 
1137         reset(mBpfNetMaps);
1138 
1139         // Remove the single-UID range. The rule for MOCK_UID11 should not change because it is
1140         // still covered by the second, multiple-UID range rule.
1141         mPermissionMonitor.updateVpnLockdownUidRanges(false /* false */, lockdownRange1);
1142         verify(mBpfNetMaps, never()).updateUidLockdownRule(anyInt(),  anyBoolean());
1143 
1144         reset(mBpfNetMaps);
1145 
1146         // Remove the multiple-UID range. Expect both UID rules to be torn down.
1147         mPermissionMonitor.updateVpnLockdownUidRanges(false /* false */, lockdownRange2);
1148         verify(mBpfNetMaps, times(2)).updateUidLockdownRule(anyInt(), eq(false) /* add */);
1149         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID13, false /* add */);
1150         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID14, false /* add */);
1151     }
1152 
1153     @Test
1154     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLockdownUidFilteringWithLockdownEnableDisableWithDuplicates()1155     public void testLockdownUidFilteringWithLockdownEnableDisableWithDuplicates() {
1156         doReturn(List.of(
1157                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
1158                         CONNECTIVITY_USE_RESTRICTED_NETWORKS),
1159                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
1160                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
1161                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1162         startMonitoring();
1163         // MOCK_UID11 is subject to the VPN.
1164         final UidRange range = new UidRange(MOCK_UID11, MOCK_UID11);
1165         final UidRange[] lockdownRangeDuplicates = {range, range};
1166         final UidRange[] lockdownRange = {range};
1167 
1168         // Add Lockdown uid ranges which contains duplicated uid ranges
1169         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRangeDuplicates);
1170         verify(mBpfNetMaps).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1171         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, true /* add */);
1172 
1173         reset(mBpfNetMaps);
1174 
1175         // Remove Lockdown uid range at 1st time, expect a rule not to be torn down because uid
1176         // ranges we added contains duplicated uid ranges.
1177         mPermissionMonitor.updateVpnLockdownUidRanges(false /* add */, lockdownRange);
1178         verify(mBpfNetMaps, never()).updateUidLockdownRule(anyInt(), anyBoolean());
1179 
1180         reset(mBpfNetMaps);
1181 
1182         // Remove Lockdown uid range at 2nd time, expect a rule to be torn down.
1183         mPermissionMonitor.updateVpnLockdownUidRanges(false /* add */, lockdownRange);
1184         verify(mBpfNetMaps).updateUidLockdownRule(anyInt(), eq(false) /* add */);
1185         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, false /* add */);
1186     }
1187 
1188     @Test
1189     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLockdownUidFilteringWithInstallAndUnInstall()1190     public void testLockdownUidFilteringWithInstallAndUnInstall() {
1191         doReturn(List.of(
1192                 buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE,
1193                         NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS),
1194                 buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID)))
1195                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1196         doReturn(List.of(MOCK_USER1, MOCK_USER2)).when(mUserManager).getUserHandles(eq(true));
1197 
1198         startMonitoring();
1199         final UidRange[] lockdownRange = {
1200                 UidRange.createForUser(MOCK_USER1),
1201                 UidRange.createForUser(MOCK_USER2)
1202         };
1203         mPermissionMonitor.updateVpnLockdownUidRanges(true /* add */, lockdownRange);
1204 
1205         reset(mBpfNetMaps);
1206 
1207         // Installing package should add Lockdown rules
1208         addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1);
1209         verify(mBpfNetMaps, times(2)).updateUidLockdownRule(anyInt(), eq(true) /* add */);
1210         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, true /* add */);
1211         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID21, true /* add */);
1212 
1213         reset(mBpfNetMaps);
1214 
1215         // Uninstalling package should remove Lockdown rules
1216         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
1217         verify(mBpfNetMaps).updateUidLockdownRule(anyInt(), eq(false) /* add */);
1218         verify(mBpfNetMaps).updateUidLockdownRule(MOCK_UID11, false /* add */);
1219     }
1220 
1221     // Normal package add/remove operations will trigger multiple intent for uids corresponding to
1222     // each user. To simulate generic package operations, the onPackageAdded/Removed will need to be
1223     // called multiple times with the uid corresponding to each user.
addPackageForUsers(UserHandle[] users, String packageName, int appId)1224     private void addPackageForUsers(UserHandle[] users, String packageName, int appId) {
1225         for (final UserHandle user : users) {
1226             onPackageAdded(packageName, user.getUid(appId));
1227         }
1228     }
1229 
removePackageForUsers(UserHandle[] users, String packageName, int appId)1230     private void removePackageForUsers(UserHandle[] users, String packageName, int appId) {
1231         for (final UserHandle user : users) {
1232             onPackageRemoved(packageName, user.getUid(appId));
1233         }
1234     }
1235 
1236     @Test
testPackagePermissionUpdate()1237     public void testPackagePermissionUpdate() throws Exception {
1238         // MOCK_APPID1: MOCK_PACKAGE1 only has internet permission.
1239         // MOCK_APPID2: MOCK_PACKAGE2 does not have any permission.
1240         // SYSTEM_APPID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission
1241         // SYSTEM_APPID2: SYSTEM_PACKAGE2 has only update device stats permission.
1242         // The SDK sandbox APPIDs must have permissions mirroring the app
1243         SparseIntArray netdPermissionsAppIds = new SparseIntArray();
1244         netdPermissionsAppIds.put(MOCK_APPID1, PERMISSION_INTERNET);
1245         if (hasSdkSandbox(MOCK_APPID1)) {
1246             netdPermissionsAppIds.put(mProcessShim.toSdkSandboxUid(MOCK_APPID1),
1247                     PERMISSION_INTERNET);
1248         }
1249         netdPermissionsAppIds.put(MOCK_APPID2, PERMISSION_NONE);
1250         if (hasSdkSandbox(MOCK_APPID2)) {
1251             netdPermissionsAppIds.put(mProcessShim.toSdkSandboxUid(MOCK_APPID2),
1252                     PERMISSION_NONE);
1253         }
1254         netdPermissionsAppIds.put(SYSTEM_APPID1, PERMISSION_TRAFFIC_ALL);
1255         netdPermissionsAppIds.put(SYSTEM_APPID2, PERMISSION_UPDATE_DEVICE_STATS);
1256 
1257         // Send the permission information to netd, expect permission updated.
1258         sendAppIdsTrafficPermission(netdPermissionsAppIds);
1259 
1260         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1261         mBpfMapMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID2);
1262         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, SYSTEM_APPID1);
1263         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, SYSTEM_APPID2);
1264 
1265         // Update permission of MOCK_APPID1, expect new permission show up.
1266         sendPackagePermissionsForAppId(MOCK_APPID1, PERMISSION_TRAFFIC_ALL);
1267         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1268 
1269         // Change permissions of SYSTEM_APPID2, expect new permission show up and old permission
1270         // revoked.
1271         sendPackagePermissionsForAppId(SYSTEM_APPID2, PERMISSION_INTERNET);
1272         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, SYSTEM_APPID2);
1273 
1274         // Revoke permission from SYSTEM_APPID1, expect no permission stored.
1275         sendPackagePermissionsForAppId(SYSTEM_APPID1, PERMISSION_NONE);
1276         mBpfMapMonitor.expectTrafficPerm(PERMISSION_NONE, SYSTEM_APPID1);
1277     }
1278 
1279     @Test
1280     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testPackageInstall()1281     public void testPackageInstall() throws Exception {
1282         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS);
1283         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1284 
1285         addPackage(MOCK_PACKAGE2, MOCK_UID12, INTERNET);
1286         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID2);
1287     }
1288 
1289     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
1290     @Test
1291     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLocalNetRestrictions_onPackageInstall()1292     public void testLocalNetRestrictions_onPackageInstall() throws Exception {
1293         assumeTrue(BpfNetMaps.isAtLeast25Q2());
1294         doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt());
1295         when(mPermissionManager.checkPermissionForPreflight(
1296                 anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED);
1297         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET);
1298         assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1299 
1300         addPackage(MOCK_PACKAGE2, MOCK_UID12, ACCESS_LOCAL_NETWORK);
1301         assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID12));
1302         if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid(
1303                 mProcessShim.toSdkSandboxUid(MOCK_UID12)));
1304     }
1305 
1306     @Test
1307     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testPackageInstallSharedUid()1308     public void testPackageInstallSharedUid() throws Exception {
1309         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS);
1310         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1311 
1312         // Install another package with the same uid and no permissions should not cause the appId
1313         // to lose permissions.
1314         addPackage(MOCK_PACKAGE2, MOCK_UID11);
1315         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1316     }
1317 
1318     @Test
1319     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testPackageUninstallBasic()1320     public void testPackageUninstallBasic() throws Exception {
1321         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS);
1322         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1323 
1324         when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{});
1325         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
1326         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1);
1327     }
1328 
1329     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
1330     @Test
1331     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLocalNetRestrictions_onPackageUninstall()1332     public void testLocalNetRestrictions_onPackageUninstall() throws Exception {
1333         assumeTrue(BpfNetMaps.isAtLeast25Q2());
1334         doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt());
1335         when(mPermissionManager.checkPermissionForPreflight(
1336                 anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED);
1337         addPackage(MOCK_PACKAGE1, MOCK_UID11, ACCESS_LOCAL_NETWORK);
1338         assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1339 
1340         when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{});
1341         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
1342         assertFalse(mBpfMapMonitor.isUidPresentInLocalNetBlockMap(MOCK_UID11));
1343     }
1344 
1345     @Test
1346     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testPackageRemoveThenAdd()1347     public void testPackageRemoveThenAdd() throws Exception {
1348         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS);
1349         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1350 
1351         when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{});
1352         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
1353         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1);
1354 
1355         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET);
1356         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1357     }
1358 
1359     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
1360     @Test
1361     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testLocalNetRestrictions_onPackageRemoveThenAdd()1362     public void testLocalNetRestrictions_onPackageRemoveThenAdd() throws Exception {
1363         assumeTrue(BpfNetMaps.isAtLeast25Q2());
1364         doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt());
1365         when(mPermissionManager.checkPermissionForPreflight(
1366                 anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED);
1367         addPackage(MOCK_PACKAGE1, MOCK_UID11, ACCESS_LOCAL_NETWORK);
1368         assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1369         if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid(
1370                 mProcessShim.toSdkSandboxUid(MOCK_UID11)));
1371 
1372         removePackage(MOCK_PACKAGE1, MOCK_UID11);
1373         assertFalse(mBpfMapMonitor.isUidPresentInLocalNetBlockMap(MOCK_UID11));
1374 
1375         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET);
1376         assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1377         if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid(
1378                 mProcessShim.toSdkSandboxUid(MOCK_UID11)));
1379     }
1380 
1381     @Test
1382     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testPackageUpdate()1383     public void testPackageUpdate() throws Exception {
1384         addPackage(MOCK_PACKAGE1, MOCK_UID11);
1385         mBpfMapMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1);
1386 
1387         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET);
1388         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1389     }
1390 
1391     @Test
1392     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testPackageUninstallWithMultiplePackages()1393     public void testPackageUninstallWithMultiplePackages() throws Exception {
1394         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS);
1395         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1396 
1397         // Install another package with the same uid but different permissions.
1398         addPackage(MOCK_PACKAGE2, MOCK_UID11, INTERNET);
1399         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID11);
1400 
1401         // Uninstall MOCK_PACKAGE1 and expect only INTERNET permission left.
1402         when(mPackageManager.getPackagesForUid(eq(MOCK_UID11)))
1403                 .thenReturn(new String[]{MOCK_PACKAGE2});
1404         onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11);
1405         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1406     }
1407 
1408     @Test
testRealSystemPermission()1409     public void testRealSystemPermission() throws Exception {
1410         // Use the real context as this test must ensure the *real* system package holds the
1411         // necessary permission.
1412         final Context realContext = InstrumentationRegistry.getContext();
1413         final PermissionMonitor monitor = runAsShell(
1414                 OBSERVE_GRANT_REVOKE_PERMISSIONS,
1415                 () -> new PermissionMonitor(realContext, mNetdService, mBpfNetMaps, mHandlerThread)
1416         );
1417         final PackageManager manager = realContext.getPackageManager();
1418         final PackageInfo systemInfo = manager.getPackageInfo(REAL_SYSTEM_PACKAGE_NAME,
1419                 GET_PERMISSIONS | MATCH_ANY_USER);
1420         assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
1421     }
1422 
1423     @Test
1424     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
testUpdateUidPermissionsFromSystemConfig()1425     public void testUpdateUidPermissionsFromSystemConfig() throws Exception {
1426         when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET)))
1427                 .thenReturn(new int[]{ MOCK_UID11, MOCK_UID12 });
1428         when(mSystemConfigManager.getSystemPermissionUids(eq(UPDATE_DEVICE_STATS)))
1429                 .thenReturn(new int[]{ MOCK_UID12 });
1430 
1431         startMonitoring();
1432         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1433         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID2);
1434     }
1435 
expectBroadcastReceiver(String... actions)1436     private BroadcastReceiver expectBroadcastReceiver(String... actions) {
1437         final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
1438                 ArgumentCaptor.forClass(BroadcastReceiver.class);
1439         verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(),
1440                 argThat(filter -> {
1441                     for (String action : actions) {
1442                         if (!filter.hasAction(action)) {
1443                             return false;
1444                         }
1445                     }
1446                     return true;
1447                 }), any(), any());
1448         final BroadcastReceiver originalReceiver = receiverCaptor.getValue();
1449         return new BroadcastReceiver() {
1450             @Override
1451             public void onReceive(Context context, Intent intent) {
1452                 processOnHandlerThread(() -> originalReceiver.onReceive(context, intent));
1453             }
1454         };
1455     }
1456 
1457     private void processOnHandlerThread(Runnable function) {
1458         final Handler handler = mHandlerThread.getThreadHandler();
1459         handler.post(() -> function.run());
1460         HandlerUtils.waitForIdle(mHandlerThread, TIMEOUT_MS);
1461     }
1462 
1463     @Test
1464     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1465     public void testIntentReceiver() throws Exception {
1466         startMonitoring();
1467         final BroadcastReceiver receiver = expectBroadcastReceiver(
1468                 Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_REMOVED);
1469 
1470         // Verify receiving PACKAGE_ADDED intent.
1471         final Intent addedIntent = new Intent(Intent.ACTION_PACKAGE_ADDED,
1472                 Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
1473         addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID11);
1474         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, INTERNET,
1475                 UPDATE_DEVICE_STATS);
1476         receiver.onReceive(mContext, addedIntent);
1477         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1478 
1479         // Verify receiving PACKAGE_REMOVED intent.
1480         when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{});
1481         final Intent removedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED,
1482                 Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
1483         removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID11);
1484         receiver.onReceive(mContext, removedIntent);
1485         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1);
1486     }
1487 
1488     private ContentObserver expectRegisterContentObserver(Uri expectedUri) {
1489         final ArgumentCaptor<ContentObserver> captor =
1490                 ArgumentCaptor.forClass(ContentObserver.class);
1491         verify(mDeps).registerContentObserver(any(),
1492                 argThat(uri -> uri.equals(expectedUri)), anyBoolean(), captor.capture());
1493         final ContentObserver originalObserver = captor.getValue();
1494         return new ContentObserver(null) {
1495             @Override
1496             public void onChange(final boolean selfChange) {
1497                 processOnHandlerThread(() -> originalObserver.onChange(selfChange));
1498             }
1499         };
1500     }
1501 
1502     @Test
1503     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1504     public void testUidsAllowedOnRestrictedNetworksChanged() throws Exception {
1505         startMonitoring();
1506         final ContentObserver contentObserver = expectRegisterContentObserver(
1507                 Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
1508 
1509         // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2
1510         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11);
1511         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12);
1512 
1513         // MOCK_UID11 is listed in setting that allow to use restricted networks, MOCK_UID11
1514         // should have SYSTEM permission.
1515         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID11));
1516         contentObserver.onChange(true /* selfChange */);
1517         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1518                 MOCK_APPID1);
1519         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2);
1520 
1521         // MOCK_UID12 is listed in setting that allow to use restricted networks, MOCK_UID12
1522         // should have SYSTEM permission but MOCK_UID11 should revoke permission.
1523         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID12));
1524         contentObserver.onChange(true /* selfChange */);
1525         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1526                 MOCK_APPID2);
1527         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1);
1528 
1529         // No uid lists in setting, should revoke permission from all uids.
1530         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of());
1531         contentObserver.onChange(true /* selfChange */);
1532         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1, MOCK_APPID2);
1533     }
1534 
1535     @Test
1536     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1537     public void testUidsAllowedOnRestrictedNetworksChangedWithSharedUid() throws Exception {
1538         startMonitoring();
1539         final ContentObserver contentObserver = expectRegisterContentObserver(
1540                 Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
1541 
1542         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE);
1543         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID11);
1544 
1545         // MOCK_PACKAGE1 have CHANGE_NETWORK_STATE, MOCK_UID11 should have NETWORK permission.
1546         addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_APPID1);
1547         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
1548                 MOCK_APPID1);
1549 
1550         // MOCK_UID11 is listed in setting that allow to use restricted networks, MOCK_UID11
1551         // should upgrade to SYSTEM permission.
1552         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID11));
1553         contentObserver.onChange(true /* selfChange */);
1554         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1555                 MOCK_APPID1);
1556 
1557         // No app lists in setting, MOCK_UID11 should downgrade to NETWORK permission.
1558         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of());
1559         contentObserver.onChange(true /* selfChange */);
1560         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
1561                 MOCK_APPID1);
1562 
1563         // MOCK_PACKAGE1 removed, should revoke permission from MOCK_UID11.
1564         when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{MOCK_PACKAGE2});
1565         removePackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_APPID1);
1566         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1);
1567     }
1568 
1569     @Test
1570     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1571     public void testUidsAllowedOnRestrictedNetworksChangedWithMultipleUsers() throws Exception {
1572         startMonitoring();
1573         final ContentObserver contentObserver = expectRegisterContentObserver(
1574                 Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
1575 
1576         // Prepare PackageInfo for MOCK_APPID1 and MOCK_APPID2 in MOCK_USER1.
1577         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11);
1578         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12);
1579 
1580         // MOCK_UID11 is listed in setting that allow to use restricted networks, MOCK_UID11 should
1581         // have SYSTEM permission and MOCK_UID12 has no permissions.
1582         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID11));
1583         contentObserver.onChange(true /* selfChange */);
1584         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1585                 MOCK_APPID1);
1586         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2);
1587 
1588         // Add user MOCK_USER2.
1589         final List<PackageInfo> pkgs = List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID21));
1590         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID22);
1591         doReturn(pkgs).when(mPackageManager)
1592                 .getInstalledPackagesAsUser(eq(GET_PERMISSIONS), eq(MOCK_USER_ID2));
1593         onUserAdded(MOCK_USER2);
1594         // MOCK_APPID1 in MOCK_USER1 should have SYSTEM permission but in MOCK_USER2 should have no
1595         // permissions. And MOCK_APPID2 has no permissions in either users.
1596         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1597                 MOCK_APPID1);
1598         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER2}, MOCK_APPID1);
1599         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_APPID2);
1600 
1601         // MOCK_UID22 is listed in setting that allow to use restricted networks,
1602         // MOCK_APPID2 in MOCK_USER2 should have SYSTEM permission but in MOCK_USER1 should have no
1603         // permissions. And MOCK_APPID1 has no permissions in either users.
1604         doReturn(Set.of(MOCK_UID22)).when(mDeps).getUidsAllowedOnRestrictedNetworks(any());
1605         contentObserver.onChange(true /* selfChange */);
1606         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER2},
1607                 MOCK_APPID2);
1608         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2);
1609         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_APPID1);
1610 
1611         // Remove user MOCK_USER1
1612         onUserRemoved(MOCK_USER1);
1613         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER2},
1614                 MOCK_APPID2);
1615         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER2}, MOCK_APPID1);
1616         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2);
1617 
1618         // No uid lists in setting, should revoke permission from all uids.
1619         when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of());
1620         contentObserver.onChange(true /* selfChange */);
1621         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER2}, MOCK_APPID1, MOCK_APPID2);
1622     }
1623 
1624     @Test
1625     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1626     public void testOnExternalApplicationsAvailable() throws Exception {
1627         // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external
1628         // and have different uids. There has no permission for both uids.
1629         doReturn(List.of(
1630                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
1631                 buildPackageInfo(MOCK_PACKAGE2, MOCK_UID12)))
1632                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1633         startMonitoring();
1634         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1, MOCK_APPID2);
1635         mBpfMapMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1, MOCK_APPID2);
1636 
1637         final BroadcastReceiver receiver = expectBroadcastReceiver(
1638                 Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1639         // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
1640         final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1641         externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST,
1642                 new String[] { MOCK_PACKAGE1 , MOCK_PACKAGE2});
1643         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11,
1644                 CONNECTIVITY_USE_RESTRICTED_NETWORKS, INTERNET);
1645         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12, CHANGE_NETWORK_STATE,
1646                 UPDATE_DEVICE_STATS);
1647         receiver.onReceive(mContext, externalIntent);
1648         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1649                 MOCK_APPID1);
1650         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
1651                 MOCK_APPID2);
1652         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1653         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, MOCK_APPID2);
1654     }
1655 
1656     @Test
1657     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1658     public void testOnExternalApplicationsAvailable_AppsNotRegisteredOnStartMonitoring()
1659             throws Exception {
1660         startMonitoring();
1661         final BroadcastReceiver receiver = expectBroadcastReceiver(
1662                 Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1663 
1664         // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external
1665         // and have different uids. There has no permission for both uids.
1666         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11,
1667                 CONNECTIVITY_USE_RESTRICTED_NETWORKS, INTERNET);
1668         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12, CHANGE_NETWORK_STATE,
1669                 UPDATE_DEVICE_STATS);
1670 
1671         // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
1672         final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1673         externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST,
1674                 new String[] { MOCK_PACKAGE1 , MOCK_PACKAGE2});
1675         receiver.onReceive(mContext, externalIntent);
1676         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1677                 MOCK_APPID1);
1678         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
1679                 MOCK_APPID2);
1680         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1681         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, MOCK_APPID2);
1682     }
1683 
1684     @Test
1685     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1686     public void testOnExternalApplicationsAvailableWithSharedUid()
1687             throws Exception {
1688         // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external
1689         // storage and shared on MOCK_UID11. There has no permission for MOCK_UID11.
1690         doReturn(List.of(
1691                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
1692                 buildPackageInfo(MOCK_PACKAGE2, MOCK_UID11)))
1693                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1694         startMonitoring();
1695         mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1);
1696         mBpfMapMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1);
1697 
1698         final BroadcastReceiver receiver = expectBroadcastReceiver(
1699                 Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1700         // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
1701         final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1702         externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST, new String[] {MOCK_PACKAGE1});
1703         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE);
1704         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID11, UPDATE_DEVICE_STATS);
1705         receiver.onReceive(mContext, externalIntent);
1706         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
1707                 MOCK_APPID1);
1708         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UPDATE_DEVICE_STATS, MOCK_APPID1);
1709     }
1710 
1711     @Test
1712     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1713     public void testOnExternalApplicationsAvailableWithSharedUid_DifferentStorage()
1714             throws Exception {
1715         // Initial the permission state. MOCK_PACKAGE1 is installed on external storage and
1716         // MOCK_PACKAGE2 is installed on device. These two packages are shared on MOCK_UID11.
1717         // MOCK_UID11 has NETWORK and INTERNET permissions.
1718         doReturn(List.of(
1719                 buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11),
1720                 buildPackageInfo(MOCK_PACKAGE2, MOCK_UID11, CHANGE_NETWORK_STATE, INTERNET)))
1721                 .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
1722         startMonitoring();
1723         mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1},
1724                 MOCK_APPID1);
1725         mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1);
1726 
1727         final BroadcastReceiver receiver = expectBroadcastReceiver(
1728                 Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1729         // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd.
1730         final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1731         externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST, new String[] {MOCK_PACKAGE1});
1732         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11,
1733                 CONNECTIVITY_USE_RESTRICTED_NETWORKS, UPDATE_DEVICE_STATS);
1734         buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID11, CHANGE_NETWORK_STATE,
1735                 INTERNET);
1736         receiver.onReceive(mContext, externalIntent);
1737         mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},
1738                 MOCK_APPID1);
1739         mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1);
1740     }
1741 
1742     @Test
1743     public void testIsHigherNetworkPermission() {
1744         assertFalse(isHigherNetworkPermission(PERMISSION_NONE, PERMISSION_NONE));
1745         assertFalse(isHigherNetworkPermission(PERMISSION_NONE, PERMISSION_NETWORK));
1746         assertFalse(isHigherNetworkPermission(PERMISSION_NONE, PERMISSION_SYSTEM));
1747         assertTrue(isHigherNetworkPermission(PERMISSION_NETWORK, PERMISSION_NONE));
1748         assertFalse(isHigherNetworkPermission(PERMISSION_NETWORK, PERMISSION_NETWORK));
1749         assertFalse(isHigherNetworkPermission(PERMISSION_NETWORK, PERMISSION_SYSTEM));
1750         assertTrue(isHigherNetworkPermission(PERMISSION_SYSTEM, PERMISSION_NONE));
1751         assertTrue(isHigherNetworkPermission(PERMISSION_SYSTEM, PERMISSION_NETWORK));
1752         assertFalse(isHigherNetworkPermission(PERMISSION_SYSTEM, PERMISSION_SYSTEM));
1753     }
1754 
1755     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
1756     @Test
1757     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1758     public void testLocalNetRestrictions_setPermChanges() throws Exception {
1759         assumeTrue(BpfNetMaps.isAtLeast25Q2());
1760         doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt());
1761         when(mPermissionManager.checkPermissionForPreflight(
1762                 anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED);
1763         addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET);
1764         assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1765 
1766         // Mock permission grant
1767         when(mPermissionManager.checkPermissionForPreflight(
1768                 eq(ACCESS_LOCAL_NETWORK),
1769                 argThat(attributionSource -> attributionSource.getUid() == MOCK_UID11)))
1770                 .thenReturn(PERMISSION_GRANTED);
1771         mPermissionMonitor.setLocalNetworkPermissions(MOCK_UID11, null);
1772         assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1773         if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid(
1774                 mProcessShim.toSdkSandboxUid(MOCK_UID11)));
1775 
1776         // Mock permission denied
1777         when(mPermissionManager.checkPermissionForPreflight(
1778                 eq(ACCESS_LOCAL_NETWORK),
1779                 argThat(attributionSource -> attributionSource.getUid() == MOCK_UID11)))
1780                 .thenReturn(PERMISSION_DENIED);
1781         mPermissionMonitor.setLocalNetworkPermissions(MOCK_UID11, null);
1782         assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11));
1783         if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid(
1784                 mProcessShim.toSdkSandboxUid(MOCK_UID11)));
1785     }
1786 
1787     private void prepareMultiUserPackages() {
1788         // MOCK_USER1 has installed 3 packages
1789         // mockApp1 has no permission and share MOCK_APPID1.
1790         // mockApp2 has INTERNET permission and share MOCK_APPID2.
1791         // mockApp3 has UPDATE_DEVICE_STATS permission and share MOCK_APPID3.
1792         final List<PackageInfo> pkgs1 = List.of(
1793                 buildPackageInfo("mockApp1", MOCK_UID11),
1794                 buildPackageInfo("mockApp2", MOCK_UID12, INTERNET),
1795                 buildPackageInfo("mockApp3", MOCK_UID13, UPDATE_DEVICE_STATS));
1796 
1797         // MOCK_USER2 has installed 2 packages
1798         // mockApp4 has UPDATE_DEVICE_STATS permission and share MOCK_APPID1.
1799         // mockApp5 has INTERNET permission and share MOCK_APPID2.
1800         final List<PackageInfo> pkgs2 = List.of(
1801                 buildPackageInfo("mockApp4", MOCK_UID21, UPDATE_DEVICE_STATS),
1802                 buildPackageInfo("mockApp5", MOCK_UID23, INTERNET));
1803 
1804         // MOCK_USER3 has installed 1 packages
1805         // mockApp6 has UPDATE_DEVICE_STATS permission and share MOCK_APPID2.
1806         final List<PackageInfo> pkgs3 = List.of(
1807                 buildPackageInfo("mockApp6", MOCK_UID32, UPDATE_DEVICE_STATS));
1808 
1809         doReturn(pkgs1).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
1810                 eq(MOCK_USER_ID1));
1811         doReturn(pkgs2).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
1812                 eq(MOCK_USER_ID2));
1813         doReturn(pkgs3).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS),
1814                 eq(MOCK_USER_ID3));
1815     }
1816 
1817     private void addUserAndVerifyAppIdsPermissions(UserHandle user, int appId1Perm,
1818             int appId2Perm, int appId3Perm) {
1819         onUserAdded(user);
1820         mBpfMapMonitor.expectTrafficPerm(appId1Perm, MOCK_APPID1);
1821         mBpfMapMonitor.expectTrafficPerm(appId2Perm, MOCK_APPID2);
1822         mBpfMapMonitor.expectTrafficPerm(appId3Perm, MOCK_APPID3);
1823     }
1824 
1825     private void removeUserAndVerifyAppIdsPermissions(UserHandle user, int appId1Perm,
1826             int appId2Perm, int appId3Perm) {
1827         onUserRemoved(user);
1828         mBpfMapMonitor.expectTrafficPerm(appId1Perm, MOCK_APPID1);
1829         mBpfMapMonitor.expectTrafficPerm(appId2Perm, MOCK_APPID2);
1830         mBpfMapMonitor.expectTrafficPerm(appId3Perm, MOCK_APPID3);
1831     }
1832 
1833     @Test
1834     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1835     public void testAppIdsTrafficPermission_UserAddedRemoved() {
1836         prepareMultiUserPackages();
1837 
1838         // Add MOCK_USER1 and verify the permissions with each appIds.
1839         addUserAndVerifyAppIdsPermissions(MOCK_USER1, PERMISSION_NONE, PERMISSION_INTERNET,
1840                 PERMISSION_UPDATE_DEVICE_STATS);
1841 
1842         // Add MOCK_USER2 and verify the permissions upgrade on MOCK_APPID1 & MOCK_APPID3.
1843         addUserAndVerifyAppIdsPermissions(MOCK_USER2, PERMISSION_UPDATE_DEVICE_STATS,
1844                 PERMISSION_INTERNET, PERMISSION_TRAFFIC_ALL);
1845 
1846         // Add MOCK_USER3 and verify the permissions upgrade on MOCK_APPID2.
1847         addUserAndVerifyAppIdsPermissions(MOCK_USER3, PERMISSION_UPDATE_DEVICE_STATS,
1848                 PERMISSION_TRAFFIC_ALL, PERMISSION_TRAFFIC_ALL);
1849 
1850         // Remove MOCK_USER2 and verify the permissions downgrade on MOCK_APPID1 & MOCK_APPID3.
1851         removeUserAndVerifyAppIdsPermissions(MOCK_USER2, PERMISSION_NONE, PERMISSION_TRAFFIC_ALL,
1852                 PERMISSION_UPDATE_DEVICE_STATS);
1853 
1854         // Remove MOCK_USER1 and verify the permissions downgrade on all appIds.
1855         removeUserAndVerifyAppIdsPermissions(MOCK_USER1, PERMISSION_UNINSTALLED,
1856                 PERMISSION_UPDATE_DEVICE_STATS, PERMISSION_UNINSTALLED);
1857 
1858         // Add MOCK_USER2 back and verify the permissions upgrade on MOCK_APPID1 & MOCK_APPID3.
1859         addUserAndVerifyAppIdsPermissions(MOCK_USER2, PERMISSION_UPDATE_DEVICE_STATS,
1860                 PERMISSION_UPDATE_DEVICE_STATS, PERMISSION_INTERNET);
1861 
1862         // Remove MOCK_USER3 and verify the permissions downgrade on MOCK_APPID2.
1863         removeUserAndVerifyAppIdsPermissions(MOCK_USER3, PERMISSION_UPDATE_DEVICE_STATS,
1864                 PERMISSION_UNINSTALLED, PERMISSION_INTERNET);
1865     }
1866 
1867     @Test
1868     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1869     public void testAppIdsTrafficPermission_Multiuser_PackageAdded() throws Exception {
1870         // Add two users with empty package list.
1871         onUserAdded(MOCK_USER1);
1872         onUserAdded(MOCK_USER2);
1873 
1874         final int[] netdPermissions = {PERMISSION_NONE, PERMISSION_INTERNET,
1875                 PERMISSION_UPDATE_DEVICE_STATS, PERMISSION_TRAFFIC_ALL};
1876         final String[][] grantPermissions = {new String[]{}, new String[]{INTERNET},
1877                 new String[]{UPDATE_DEVICE_STATS}, new String[]{INTERNET, UPDATE_DEVICE_STATS}};
1878 
1879         // Verify that the permission combination is expected when same appId package is installed
1880         // on another user. List the expected permissions below.
1881         // NONE                + NONE                = NONE
1882         // NONE                + INTERNET            = INTERNET
1883         // NONE                + UPDATE_DEVICE_STATS = UPDATE_DEVICE_STATS
1884         // NONE                + ALL                 = ALL
1885         // INTERNET            + NONE                = INTERNET
1886         // INTERNET            + INTERNET            = INTERNET
1887         // INTERNET            + UPDATE_DEVICE_STATS = ALL
1888         // INTERNET            + ALL                 = ALL
1889         // UPDATE_DEVICE_STATS + NONE                = UPDATE_DEVICE_STATS
1890         // UPDATE_DEVICE_STATS + INTERNET            = ALL
1891         // UPDATE_DEVICE_STATS + UPDATE_DEVICE_STATS = UPDATE_DEVICE_STATS
1892         // UPDATE_DEVICE_STATS + ALL                 = ALL
1893         // ALL                 + NONE                = ALL
1894         // ALL                 + INTERNET            = ALL
1895         // ALL                 + UPDATE_DEVICE_STATS = ALL
1896         // ALL                 + ALL                 = ALL
1897         for (int i = 0, num = 0; i < netdPermissions.length; i++) {
1898             final int current = netdPermissions[i];
1899             final String[] user1Perm = grantPermissions[i];
1900             for (int j = 0; j < netdPermissions.length; j++) {
1901                 final int appId = MOCK_APPID1 + num;
1902                 final int added = netdPermissions[j];
1903                 final String[] user2Perm = grantPermissions[j];
1904                 // Add package on MOCK_USER1 and verify the permission is same as package granted.
1905                 addPackage(MOCK_PACKAGE1, MOCK_USER1.getUid(appId), user1Perm);
1906                 mBpfMapMonitor.expectTrafficPerm(current, appId);
1907 
1908                 // Add package which share the same appId on MOCK_USER2, and verify the permission
1909                 // has combined.
1910                 addPackage(MOCK_PACKAGE2, MOCK_USER2.getUid(appId), user2Perm);
1911                 mBpfMapMonitor.expectTrafficPerm((current | added), appId);
1912                 num++;
1913             }
1914         }
1915     }
1916 
1917     private void verifyAppIdPermissionsAfterPackageRemoved(int appId, int expectedPerm,
1918             String[] user1Perm, String[] user2Perm) throws Exception {
1919         // Add package on MOCK_USER1 and verify the permission is same as package granted.
1920         addPackage(MOCK_PACKAGE1, MOCK_USER1.getUid(appId), user1Perm);
1921         mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
1922 
1923         // Add two packages which share the same appId and don't declare permission on
1924         // MOCK_USER2. Verify the permission has no change.
1925         addPackage(MOCK_PACKAGE2, MOCK_USER2.getUid(appId));
1926         addPackage(MOCK_PACKAGE3, MOCK_USER2.getUid(appId), user2Perm);
1927         mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
1928 
1929         // Remove one packages from MOCK_USER2. Verify the permission has no change too.
1930         removePackage(MOCK_PACKAGE2, MOCK_USER2.getUid(appId));
1931         mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
1932 
1933         // Remove last packages from MOCK_USER2. Verify the permission has still no change.
1934         removePackage(MOCK_PACKAGE3, MOCK_USER2.getUid(appId));
1935         mBpfMapMonitor.expectTrafficPerm(expectedPerm, appId);
1936     }
1937 
1938     @Test
1939     @EnableCompatChanges(RESTRICT_LOCAL_NETWORK)
1940     public void testAppIdsTrafficPermission_Multiuser_PackageRemoved() throws Exception {
1941         // Add two users with empty package list.
1942         onUserAdded(MOCK_USER1);
1943         onUserAdded(MOCK_USER2);
1944 
1945         int appId = MOCK_APPID1;
1946         // Verify that the permission combination is expected when same appId package is removed on
1947         // another user. List the expected permissions below.
1948         /***** NONE *****/
1949         // NONE + NONE = NONE
1950         verifyAppIdPermissionsAfterPackageRemoved(
1951                 appId++, PERMISSION_NONE, new String[]{}, new String[]{});
1952 
1953         /***** INTERNET *****/
1954         // INTERNET + NONE = INTERNET
1955         verifyAppIdPermissionsAfterPackageRemoved(
1956                 appId++, PERMISSION_INTERNET, new String[]{INTERNET}, new String[]{});
1957 
1958         // INTERNET + INTERNET = INTERNET
1959         verifyAppIdPermissionsAfterPackageRemoved(
1960                 appId++, PERMISSION_INTERNET, new String[]{INTERNET}, new String[]{INTERNET});
1961 
1962         /***** UPDATE_DEVICE_STATS *****/
1963         // UPDATE_DEVICE_STATS + NONE = UPDATE_DEVICE_STATS
1964         verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_UPDATE_DEVICE_STATS,
1965                 new String[]{UPDATE_DEVICE_STATS}, new String[]{});
1966 
1967         // UPDATE_DEVICE_STATS + UPDATE_DEVICE_STATS = UPDATE_DEVICE_STATS
1968         verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_UPDATE_DEVICE_STATS,
1969                 new String[]{UPDATE_DEVICE_STATS}, new String[]{UPDATE_DEVICE_STATS});
1970 
1971         /***** ALL *****/
1972         // ALL + NONE = ALL
1973         verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
1974                 new String[]{INTERNET, UPDATE_DEVICE_STATS}, new String[]{});
1975 
1976         // ALL + INTERNET = ALL
1977         verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
1978                 new String[]{INTERNET, UPDATE_DEVICE_STATS}, new String[]{INTERNET});
1979 
1980         // ALL + UPDATE_DEVICE_STATS = ALL
1981         verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
1982                 new String[]{INTERNET, UPDATE_DEVICE_STATS}, new String[]{UPDATE_DEVICE_STATS});
1983 
1984         // ALL + ALL = ALL
1985         verifyAppIdPermissionsAfterPackageRemoved(appId++, PERMISSION_TRAFFIC_ALL,
1986                 new String[]{INTERNET, UPDATE_DEVICE_STATS},
1987                 new String[]{INTERNET, UPDATE_DEVICE_STATS});
1988 
1989         /***** UNINSTALL *****/
1990         // UNINSTALL + UNINSTALL = UNINSTALL
1991         verifyAppIdPermissionsAfterPackageRemoved(
1992                 appId, PERMISSION_NONE, new String[]{}, new String[]{});
1993         removePackage(MOCK_PACKAGE1, MOCK_USER1.getUid(appId));
1994         mBpfMapMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, appId);
1995     }
1996 }
1997