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