blob: 7fee7b73cd0e58d251c6be338409bf8332ec370f [file] [log] [blame]
Chalard Jean26aa91a2018-03-20 19:13:57 +09001/*
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
17package com.android.server.connectivity;
18
19import static android.Manifest.permission.CHANGE_NETWORK_STATE;
20import static android.Manifest.permission.CHANGE_WIFI_STATE;
21import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
22import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
Chenbo Feng436fe582019-02-25 22:55:58 -080023import static android.Manifest.permission.INTERNET;
Chalard Jean26aa91a2018-03-20 19:13:57 +090024import static android.Manifest.permission.NETWORK_STACK;
Chenbo Feng436fe582019-02-25 22:55:58 -080025import static android.Manifest.permission.UPDATE_DEVICE_STATS;
paulhub6733802018-08-20 11:01:21 +080026import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
27import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
28import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
Chenbo Feng436fe582019-02-25 22:55:58 -080029import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
paulhu86e23eb2019-11-05 18:05:05 +080030import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED;
Chalard Jean26aa91a2018-03-20 19:13:57 +090031import static android.content.pm.PackageManager.GET_PERMISSIONS;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000032import static android.content.pm.PackageManager.MATCH_ANY_USER;
paulhu3b0f5ea2018-11-01 10:38:11 +080033import static android.os.Process.SYSTEM_UID;
Chalard Jean26aa91a2018-03-20 19:13:57 +090034
junyulai2454b692018-11-01 17:16:31 +080035import static com.android.server.connectivity.PermissionMonitor.NETWORK;
36import static com.android.server.connectivity.PermissionMonitor.SYSTEM;
37
38import static junit.framework.Assert.fail;
39
paulhu86e23eb2019-11-05 18:05:05 +080040import static org.junit.Assert.assertEquals;
Chalard Jean26aa91a2018-03-20 19:13:57 +090041import static org.junit.Assert.assertFalse;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000042import static org.junit.Assert.assertNull;
Chalard Jean26aa91a2018-03-20 19:13:57 +090043import static org.junit.Assert.assertTrue;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000044import static org.mockito.AdditionalMatchers.aryEq;
junyulai2454b692018-11-01 17:16:31 +080045import static org.mockito.ArgumentMatchers.any;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000046import static org.mockito.ArgumentMatchers.anyInt;
47import static org.mockito.ArgumentMatchers.anyString;
48import static org.mockito.ArgumentMatchers.eq;
junyulai2454b692018-11-01 17:16:31 +080049import static org.mockito.Mockito.doAnswer;
junyulai345155e2018-11-09 12:37:16 +080050import static org.mockito.Mockito.doReturn;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000051import static org.mockito.Mockito.reset;
junyulai345155e2018-11-09 12:37:16 +080052import static org.mockito.Mockito.spy;
Chenbo Feng436fe582019-02-25 22:55:58 -080053import static org.mockito.Mockito.verify;
Chalard Jean26aa91a2018-03-20 19:13:57 +090054import static org.mockito.Mockito.when;
55
56import android.content.Context;
57import android.content.pm.ApplicationInfo;
58import android.content.pm.PackageInfo;
Chenbo Feng436fe582019-02-25 22:55:58 -080059import android.content.pm.PackageList;
Chalard Jean26aa91a2018-03-20 19:13:57 +090060import android.content.pm.PackageManager;
Chenbo Feng436fe582019-02-25 22:55:58 -080061import android.content.pm.PackageManagerInternal;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000062import android.content.pm.UserInfo;
Chenbo Feng436fe582019-02-25 22:55:58 -080063import android.net.INetd;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000064import android.net.UidRange;
paulhub6733802018-08-20 11:01:21 +080065import android.os.Build;
junyulai2454b692018-11-01 17:16:31 +080066import android.os.UserHandle;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000067import android.os.UserManager;
Chenbo Feng436fe582019-02-25 22:55:58 -080068import android.util.SparseIntArray;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080069
Chalard Jean506686b2019-05-23 18:30:38 +090070import androidx.test.InstrumentationRegistry;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080071import androidx.test.filters.SmallTest;
72import androidx.test.runner.AndroidJUnit4;
Chalard Jean26aa91a2018-03-20 19:13:57 +090073
Chenbo Feng436fe582019-02-25 22:55:58 -080074import com.android.server.LocalServices;
75
Chalard Jean26aa91a2018-03-20 19:13:57 +090076import org.junit.Before;
77import org.junit.Test;
78import org.junit.runner.RunWith;
Chenbo Feng436fe582019-02-25 22:55:58 -080079import org.mockito.ArgumentCaptor;
Chalard Jean26aa91a2018-03-20 19:13:57 +090080import org.mockito.Mock;
81import org.mockito.MockitoAnnotations;
junyulai2454b692018-11-01 17:16:31 +080082import org.mockito.invocation.InvocationOnMock;
83
Chenbo Feng436fe582019-02-25 22:55:58 -080084import java.util.ArrayList;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000085import java.util.Arrays;
86import java.util.Collections;
junyulai2454b692018-11-01 17:16:31 +080087import java.util.HashMap;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000088import java.util.HashSet;
89import java.util.Set;
90
Chalard Jean26aa91a2018-03-20 19:13:57 +090091
92@RunWith(AndroidJUnit4.class)
93@SmallTest
94public class PermissionMonitorTest {
junyulai2454b692018-11-01 17:16:31 +080095 private static final int MOCK_USER1 = 0;
96 private static final int MOCK_USER2 = 1;
97 private static final int MOCK_UID1 = 10001;
Chenbo Feng436fe582019-02-25 22:55:58 -080098 private static final int MOCK_UID2 = 10086;
99 private static final int SYSTEM_UID1 = 1000;
100 private static final int SYSTEM_UID2 = 1008;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000101 private static final int VPN_UID = 10002;
Chalard Jean506686b2019-05-23 18:30:38 +0900102 private static final String REAL_SYSTEM_PACKAGE_NAME = "android";
junyulai2454b692018-11-01 17:16:31 +0800103 private static final String MOCK_PACKAGE1 = "appName1";
Chenbo Feng436fe582019-02-25 22:55:58 -0800104 private static final String MOCK_PACKAGE2 = "appName2";
junyulai2454b692018-11-01 17:16:31 +0800105 private static final String SYSTEM_PACKAGE1 = "sysName1";
106 private static final String SYSTEM_PACKAGE2 = "sysName2";
paulhub6733802018-08-20 11:01:21 +0800107 private static final String PARTITION_SYSTEM = "system";
108 private static final String PARTITION_OEM = "oem";
109 private static final String PARTITION_PRODUCT = "product";
110 private static final String PARTITION_VENDOR = "vendor";
paulhu3b0f5ea2018-11-01 10:38:11 +0800111 private static final int VERSION_P = Build.VERSION_CODES.P;
112 private static final int VERSION_Q = Build.VERSION_CODES.Q;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900113
114 @Mock private Context mContext;
115 @Mock private PackageManager mPackageManager;
Chenbo Feng436fe582019-02-25 22:55:58 -0800116 @Mock private INetd mNetdService;
117 @Mock private PackageManagerInternal mMockPmi;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000118 @Mock private UserManager mUserManager;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900119
Chenbo Feng436fe582019-02-25 22:55:58 -0800120 private PackageManagerInternal.PackageListObserver mObserver;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900121 private PermissionMonitor mPermissionMonitor;
122
123 @Before
124 public void setUp() throws Exception {
125 MockitoAnnotations.initMocks(this);
126 when(mContext.getPackageManager()).thenReturn(mPackageManager);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000127 when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
128 when(mUserManager.getUsers(eq(true))).thenReturn(
129 Arrays.asList(new UserInfo[] {
130 new UserInfo(MOCK_USER1, "", 0),
131 new UserInfo(MOCK_USER2, "", 0),
132 }));
133
134 mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService));
Chenbo Feng436fe582019-02-25 22:55:58 -0800135
136 LocalServices.removeServiceForTest(PackageManagerInternal.class);
137 LocalServices.addService(PackageManagerInternal.class, mMockPmi);
138 when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(new ArrayList<String>(),
139 /* observer */ null));
140 when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
141 mPermissionMonitor.startMonitoring();
142
143 final ArgumentCaptor<PackageManagerInternal.PackageListObserver> observerCaptor =
144 ArgumentCaptor.forClass(PackageManagerInternal.PackageListObserver.class);
145 verify(mMockPmi).getPackageList(observerCaptor.capture());
146 mObserver = observerCaptor.getValue();
Chalard Jean26aa91a2018-03-20 19:13:57 +0900147 }
148
paulhu86e23eb2019-11-05 18:05:05 +0800149 private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
150 String... permissions) {
151 final PackageInfo packageInfo =
152 packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition);
paulhub6733802018-08-20 11:01:21 +0800153 packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
paulhu3b0f5ea2018-11-01 10:38:11 +0800154 packageInfo.applicationInfo.uid = uid;
paulhu86e23eb2019-11-05 18:05:05 +0800155 return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900156 }
157
paulhu86e23eb2019-11-05 18:05:05 +0800158 private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
159 return packageInfoWithPermissions(
160 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
161 }
162
163 private static PackageInfo vendorPackageInfoWithPermissions(String... permissions) {
164 return packageInfoWithPermissions(
165 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_VENDOR);
166 }
167
168 private static PackageInfo packageInfoWithPermissions(int permissionsFlags,
169 String[] permissions, String partition) {
Chenbo Feng436fe582019-02-25 22:55:58 -0800170 int[] requestedPermissionsFlags = new int[permissions.length];
171 for (int i = 0; i < permissions.length; i++) {
paulhu86e23eb2019-11-05 18:05:05 +0800172 requestedPermissionsFlags[i] = permissionsFlags;
Chenbo Feng436fe582019-02-25 22:55:58 -0800173 }
Chalard Jean26aa91a2018-03-20 19:13:57 +0900174 final PackageInfo packageInfo = new PackageInfo();
175 packageInfo.requestedPermissions = permissions;
176 packageInfo.applicationInfo = new ApplicationInfo();
Chenbo Feng436fe582019-02-25 22:55:58 -0800177 packageInfo.requestedPermissionsFlags = requestedPermissionsFlags;
paulhub6733802018-08-20 11:01:21 +0800178 int privateFlags = 0;
179 switch (partition) {
180 case PARTITION_OEM:
181 privateFlags = PRIVATE_FLAG_OEM;
182 break;
183 case PARTITION_PRODUCT:
184 privateFlags = PRIVATE_FLAG_PRODUCT;
185 break;
186 case PARTITION_VENDOR:
187 privateFlags = PRIVATE_FLAG_VENDOR;
188 break;
189 }
190 packageInfo.applicationInfo.privateFlags = privateFlags;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900191 return packageInfo;
192 }
193
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000194 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid, int userId) {
195 final PackageInfo pkgInfo;
196 if (hasSystemPermission) {
paulhu86e23eb2019-11-05 18:05:05 +0800197 pkgInfo = systemPackageInfoWithPermissions(
198 CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000199 } else {
paulhu86e23eb2019-11-05 18:05:05 +0800200 pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000201 }
202 pkgInfo.applicationInfo.uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
203 return pkgInfo;
204 }
205
Chalard Jean26aa91a2018-03-20 19:13:57 +0900206 @Test
207 public void testHasPermission() {
paulhu86e23eb2019-11-05 18:05:05 +0800208 PackageInfo app = systemPackageInfoWithPermissions();
Chalard Jean26aa91a2018-03-20 19:13:57 +0900209 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
210 assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
211 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
212 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
213
paulhu86e23eb2019-11-05 18:05:05 +0800214 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE, NETWORK_STACK);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900215 assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
216 assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
217 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
218 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
219
paulhu86e23eb2019-11-05 18:05:05 +0800220 app = systemPackageInfoWithPermissions(
221 CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900222 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
223 assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
224 assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
225 assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
paulhu86e23eb2019-11-05 18:05:05 +0800226
227 app = packageInfoWithPermissions(REQUESTED_PERMISSION_REQUIRED, new String[] {
228 CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL, NETWORK_STACK },
229 PARTITION_SYSTEM);
230 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
231 assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
232 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
233 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
234
235 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
236 app.requestedPermissions = null;
237 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
238
239 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
240 app.requestedPermissionsFlags = null;
241 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
Chalard Jean26aa91a2018-03-20 19:13:57 +0900242 }
243
244 @Test
paulhub6733802018-08-20 11:01:21 +0800245 public void testIsVendorApp() {
paulhu86e23eb2019-11-05 18:05:05 +0800246 PackageInfo app = systemPackageInfoWithPermissions();
paulhub6733802018-08-20 11:01:21 +0800247 assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
paulhu86e23eb2019-11-05 18:05:05 +0800248 app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
249 new String[] {}, PARTITION_OEM);
paulhub6733802018-08-20 11:01:21 +0800250 assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
paulhu86e23eb2019-11-05 18:05:05 +0800251 app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
252 new String[] {}, PARTITION_PRODUCT);
paulhub6733802018-08-20 11:01:21 +0800253 assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
paulhu86e23eb2019-11-05 18:05:05 +0800254 app = vendorPackageInfoWithPermissions();
paulhub6733802018-08-20 11:01:21 +0800255 assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
Chalard Jean26aa91a2018-03-20 19:13:57 +0900256 }
257
258 @Test
paulhu86e23eb2019-11-05 18:05:05 +0800259 public void testHasNetworkPermission() {
260 PackageInfo app = systemPackageInfoWithPermissions();
261 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
262 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
263 assertTrue(mPermissionMonitor.hasNetworkPermission(app));
264 app = systemPackageInfoWithPermissions(NETWORK_STACK);
265 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
266 app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS);
267 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
268 }
269
270 @Test
271 public void testHasRestrictedNetworkPermission() {
272 assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
273 assertFalse(hasRestrictedNetworkPermission(
274 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
275 assertTrue(hasRestrictedNetworkPermission(
276 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, NETWORK_STACK));
277 assertTrue(hasRestrictedNetworkPermission(
278 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
279 assertTrue(hasRestrictedNetworkPermission(
280 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
281 assertFalse(hasRestrictedNetworkPermission(
282 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
283
284 assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
285 assertFalse(hasRestrictedNetworkPermission(
286 PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CHANGE_WIFI_STATE));
287 }
288
289 @Test
290 public void testHasRestrictedNetworkPermissionSystemUid() {
291 doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt();
292 assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
293 assertTrue(hasRestrictedNetworkPermission(
294 PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CHANGE_WIFI_STATE));
295 assertTrue(hasRestrictedNetworkPermission(
296 PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
297
298 doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt();
299 assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
300 assertFalse(hasRestrictedNetworkPermission(
301 PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CHANGE_WIFI_STATE));
302 assertTrue(hasRestrictedNetworkPermission(
303 PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
304 }
305
306 @Test
307 public void testHasRestrictedNetworkPermissionVendorApp() {
308 assertTrue(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
309 assertTrue(hasRestrictedNetworkPermission(
310 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
311 assertTrue(hasRestrictedNetworkPermission(
312 PARTITION_VENDOR, VERSION_P, MOCK_UID1, NETWORK_STACK));
313 assertTrue(hasRestrictedNetworkPermission(
314 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
315 assertTrue(hasRestrictedNetworkPermission(
316 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
317 assertTrue(hasRestrictedNetworkPermission(
318 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
319
320 assertFalse(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
321 assertFalse(hasRestrictedNetworkPermission(
322 PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_WIFI_STATE));
323 assertFalse(hasRestrictedNetworkPermission(
324 PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_NETWORK_STATE));
325 }
326
327 private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
328 String... permissions) throws Exception {
329 when(mPackageManager.getPackageInfo(eq(name), anyInt()))
330 .thenReturn(packageInfoWithPermissions(
331 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM));
332 mPermissionMonitor.onPackageAdded(name, uid);
333 assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
334 }
335
336 @Test
Chalard Jean26aa91a2018-03-20 19:13:57 +0900337 public void testHasUseBackgroundNetworksPermission() throws Exception {
paulhu86e23eb2019-11-05 18:05:05 +0800338 assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
339 assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID);
340 assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_WIFI_STATE);
341 assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE);
342 assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900343
paulhu86e23eb2019-11-05 18:05:05 +0800344 assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
345 assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID1);
346 assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID1,
347 CONNECTIVITY_USE_RESTRICTED_NETWORKS);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900348
paulhu86e23eb2019-11-05 18:05:05 +0800349 assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
350 assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2);
351 assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2,
352 CONNECTIVITY_INTERNAL);
junyulai2454b692018-11-01 17:16:31 +0800353 }
354
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000355 private class NetdMonitor {
junyulai2454b692018-11-01 17:16:31 +0800356 private final HashMap<Integer, Boolean> mApps = new HashMap<>();
357
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000358 NetdMonitor(INetd mockNetd) throws Exception {
junyulai2454b692018-11-01 17:16:31 +0800359 // Add hook to verify and track result of setPermission.
360 doAnswer((InvocationOnMock invocation) -> {
361 final Object[] args = invocation.getArguments();
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000362 final Boolean isSystem = args[0].equals(INetd.PERMISSION_SYSTEM);
junyulai2454b692018-11-01 17:16:31 +0800363 for (final int uid : (int[]) args[1]) {
364 // TODO: Currently, permission monitor will send duplicate commands for each uid
365 // corresponding to each user. Need to fix that and uncomment below test.
366 // if (mApps.containsKey(uid) && mApps.get(uid) == isSystem) {
367 // fail("uid " + uid + " is already set to " + isSystem);
368 // }
369 mApps.put(uid, isSystem);
370 }
371 return null;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000372 }).when(mockNetd).networkSetPermissionForUser(anyInt(), any(int[].class));
junyulai2454b692018-11-01 17:16:31 +0800373
374 // Add hook to verify and track result of clearPermission.
375 doAnswer((InvocationOnMock invocation) -> {
376 final Object[] args = invocation.getArguments();
377 for (final int uid : (int[]) args[0]) {
378 // TODO: Currently, permission monitor will send duplicate commands for each uid
379 // corresponding to each user. Need to fix that and uncomment below test.
380 // if (!mApps.containsKey(uid)) {
381 // fail("uid " + uid + " does not exist.");
382 // }
383 mApps.remove(uid);
384 }
385 return null;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000386 }).when(mockNetd).networkClearPermissionForUser(any(int[].class));
junyulai2454b692018-11-01 17:16:31 +0800387 }
388
389 public void expectPermission(Boolean permission, int[] users, int[] apps) {
390 for (final int user : users) {
391 for (final int app : apps) {
392 final int uid = UserHandle.getUid(user, app);
393 if (!mApps.containsKey(uid)) {
394 fail("uid " + uid + " does not exist.");
395 }
396 if (mApps.get(uid) != permission) {
397 fail("uid " + uid + " has wrong permission: " + permission);
398 }
399 }
400 }
401 }
402
403 public void expectNoPermission(int[] users, int[] apps) {
404 for (final int user : users) {
405 for (final int app : apps) {
406 final int uid = UserHandle.getUid(user, app);
407 if (mApps.containsKey(uid)) {
408 fail("uid " + uid + " has listed permissions, expected none.");
409 }
410 }
411 }
412 }
413 }
414
415 @Test
416 public void testUserAndPackageAddRemove() throws Exception {
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000417 final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
junyulai2454b692018-11-01 17:16:31 +0800418
419 // MOCK_UID1: MOCK_PACKAGE1 only has network permission.
420 // SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
421 // SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission.
422 doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM), anyString());
423 doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(any(),
424 eq(SYSTEM_PACKAGE1));
425 doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
426 eq(SYSTEM_PACKAGE2));
427 doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
428 eq(MOCK_PACKAGE1));
429
430 // Add SYSTEM_PACKAGE2, expect only have network permission.
431 mPermissionMonitor.onUserAdded(MOCK_USER1);
432 addPackageForUsers(new int[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000433 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1}, new int[]{SYSTEM_UID});
junyulai2454b692018-11-01 17:16:31 +0800434
435 // Add SYSTEM_PACKAGE1, expect permission escalate.
436 addPackageForUsers(new int[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000437 mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1}, new int[]{SYSTEM_UID});
junyulai2454b692018-11-01 17:16:31 +0800438
439 mPermissionMonitor.onUserAdded(MOCK_USER2);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000440 mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800441 new int[]{SYSTEM_UID});
442
443 addPackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000444 mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800445 new int[]{SYSTEM_UID});
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000446 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800447 new int[]{MOCK_UID1});
448
449 // Remove MOCK_UID1, expect no permission left for all user.
450 mPermissionMonitor.onPackageRemoved(MOCK_UID1);
451 removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_UID1);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000452 mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2}, new int[]{MOCK_UID1});
junyulai2454b692018-11-01 17:16:31 +0800453
454 // Remove SYSTEM_PACKAGE1, expect permission downgrade.
455 when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2});
456 removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000457 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800458 new int[]{SYSTEM_UID});
459
460 mPermissionMonitor.onUserRemoved(MOCK_USER1);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000461 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER2}, new int[]{SYSTEM_UID});
junyulai2454b692018-11-01 17:16:31 +0800462
463 // Remove all packages, expect no permission left.
464 when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{});
465 removePackageForUsers(new int[]{MOCK_USER2}, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000466 mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800467 new int[]{SYSTEM_UID, MOCK_UID1});
468
469 // Remove last user, expect no redundant clearPermission is invoked.
470 mPermissionMonitor.onUserRemoved(MOCK_USER2);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000471 mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800472 new int[]{SYSTEM_UID, MOCK_UID1});
473 }
474
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000475 @Test
476 public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
477 when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
478 Arrays.asList(new PackageInfo[] {
479 buildPackageInfo(/* SYSTEM */ true, SYSTEM_UID1, MOCK_USER1),
480 buildPackageInfo(/* SYSTEM */ false, MOCK_UID1, MOCK_USER1),
481 buildPackageInfo(/* SYSTEM */ false, MOCK_UID2, MOCK_USER1),
482 buildPackageInfo(/* SYSTEM */ false, VPN_UID, MOCK_USER1)
483 }));
484 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
485 buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
486 mPermissionMonitor.startMonitoring();
487 // Every app on user 0 except MOCK_UID2 are under VPN.
488 final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] {
489 new UidRange(0, MOCK_UID2 - 1),
490 new UidRange(MOCK_UID2 + 1, UserHandle.PER_USER_RANGE - 1)}));
491 final Set<UidRange> vpnRange2 = Collections.singleton(new UidRange(MOCK_UID2, MOCK_UID2));
492
493 // When VPN is connected, expect a rule to be set up for user app MOCK_UID1
494 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange1, VPN_UID);
495 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
496 aryEq(new int[] {MOCK_UID1}));
497
498 reset(mNetdService);
499
500 // When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated
501 mPermissionMonitor.onPackageRemoved(UserHandle.getUid(MOCK_USER1, MOCK_UID1));
502 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
503 mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
504 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
505 aryEq(new int[] {MOCK_UID1}));
506
507 reset(mNetdService);
508
509 // During VPN uid update (vpnRange1 -> vpnRange2), ConnectivityService first deletes the
510 // old UID rules then adds the new ones. Expect netd to be updated
511 mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange1, VPN_UID);
512 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
513 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange2, VPN_UID);
514 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
515 aryEq(new int[] {MOCK_UID2}));
516
517 reset(mNetdService);
518
519 // When VPN is disconnected, expect rules to be torn down
520 mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange2, VPN_UID);
521 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID2}));
522 assertNull(mPermissionMonitor.getVpnUidRanges("tun0"));
523 }
524
525 @Test
526 public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
527 when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
528 Arrays.asList(new PackageInfo[] {
529 buildPackageInfo(true, SYSTEM_UID1, MOCK_USER1),
530 buildPackageInfo(false, VPN_UID, MOCK_USER1)
531 }));
532 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
533 buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
534
535 mPermissionMonitor.startMonitoring();
536 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1));
537 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange, VPN_UID);
538
539 // Newly-installed package should have uid rules added
540 mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
541 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
542 aryEq(new int[] {MOCK_UID1}));
543
544 // Removed package should have its uid rules removed
545 mPermissionMonitor.onPackageRemoved(UserHandle.getUid(MOCK_USER1, MOCK_UID1));
546 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
547 }
548
549
junyulai2454b692018-11-01 17:16:31 +0800550 // Normal package add/remove operations will trigger multiple intent for uids corresponding to
551 // each user. To simulate generic package operations, the onPackageAdded/Removed will need to be
552 // called multiple times with the uid corresponding to each user.
553 private void addPackageForUsers(int[] users, String packageName, int uid) {
554 for (final int user : users) {
555 mPermissionMonitor.onPackageAdded(packageName, UserHandle.getUid(user, uid));
556 }
557 }
558
559 private void removePackageForUsers(int[] users, int uid) {
560 for (final int user : users) {
561 mPermissionMonitor.onPackageRemoved(UserHandle.getUid(user, uid));
562 }
Chalard Jean26aa91a2018-03-20 19:13:57 +0900563 }
Chenbo Feng436fe582019-02-25 22:55:58 -0800564
565 private class NetdServiceMonitor {
566 private final HashMap<Integer, Integer> mPermissions = new HashMap<>();
567
568 NetdServiceMonitor(INetd mockNetdService) throws Exception {
569 // Add hook to verify and track result of setPermission.
570 doAnswer((InvocationOnMock invocation) -> {
571 final Object[] args = invocation.getArguments();
572 final int permission = (int) args[0];
573 for (final int uid : (int[]) args[1]) {
574 mPermissions.put(uid, permission);
575 }
576 return null;
577 }).when(mockNetdService).trafficSetNetPermForUids(anyInt(), any(int[].class));
578 }
579
580 public void expectPermission(int permission, int[] apps) {
581 for (final int app : apps) {
582 if (!mPermissions.containsKey(app)) {
583 fail("uid " + app + " does not exist.");
584 }
585 if (mPermissions.get(app) != permission) {
586 fail("uid " + app + " has wrong permission: " + mPermissions.get(app));
587 }
588 }
589 }
590 }
591
592 @Test
593 public void testPackagePermissionUpdate() throws Exception {
594 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
595 // MOCK_UID1: MOCK_PACKAGE1 only has internet permission.
596 // MOCK_UID2: MOCK_PACKAGE2 does not have any permission.
597 // SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission.
598 // SYSTEM_UID2: SYSTEM_PACKAGE2 has only update device stats permission.
599
600 SparseIntArray netdPermissionsAppIds = new SparseIntArray();
601 netdPermissionsAppIds.put(MOCK_UID1, INetd.PERMISSION_INTERNET);
Chenbo Feng05887f92019-04-19 16:05:03 -0700602 netdPermissionsAppIds.put(MOCK_UID2, INetd.PERMISSION_NONE);
Chenbo Feng436fe582019-02-25 22:55:58 -0800603 netdPermissionsAppIds.put(SYSTEM_UID1, INetd.PERMISSION_INTERNET
604 | INetd.PERMISSION_UPDATE_DEVICE_STATS);
605 netdPermissionsAppIds.put(SYSTEM_UID2, INetd.PERMISSION_UPDATE_DEVICE_STATS);
606
607 // Send the permission information to netd, expect permission updated.
608 mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds);
609
610 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
611 new int[]{MOCK_UID1});
Chenbo Feng05887f92019-04-19 16:05:03 -0700612 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2});
Chenbo Feng436fe582019-02-25 22:55:58 -0800613 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
614 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
615 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
616 new int[]{SYSTEM_UID2});
617
618 // Update permission of MOCK_UID1, expect new permission show up.
619 mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1,
620 INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS);
621 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
622 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
623
624 // Change permissions of SYSTEM_UID2, expect new permission show up and old permission
625 // revoked.
626 mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2,
627 INetd.PERMISSION_INTERNET);
628 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
629
630 // Revoke permission from SYSTEM_UID1, expect no permission stored.
Chenbo Feng05887f92019-04-19 16:05:03 -0700631 mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.PERMISSION_NONE);
632 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
Chenbo Feng436fe582019-02-25 22:55:58 -0800633 }
634
Lorenzo Colittifc901152019-09-20 11:36:06 +0900635 private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
Chenbo Feng436fe582019-02-25 22:55:58 -0800636 throws Exception {
paulhu86e23eb2019-11-05 18:05:05 +0800637 PackageInfo packageInfo = packageInfoWithPermissions(
638 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
Chenbo Feng436fe582019-02-25 22:55:58 -0800639 when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
640 when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
Lorenzo Colittifc901152019-09-20 11:36:06 +0900641 return packageInfo;
642 }
643
644 private PackageInfo addPackage(String packageName, int uid, String[] permissions)
645 throws Exception {
646 PackageInfo packageInfo = setPackagePermissions(packageName, uid, permissions);
Chenbo Feng436fe582019-02-25 22:55:58 -0800647 mObserver.onPackageAdded(packageName, uid);
648 return packageInfo;
649 }
650
651 @Test
652 public void testPackageInstall() throws Exception {
653 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
654
655 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
656 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
657 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
658
659 addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET});
660 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
661 }
662
663 @Test
664 public void testPackageInstallSharedUid() throws Exception {
665 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
666
667 PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
668 new String[] {INTERNET, UPDATE_DEVICE_STATS});
669 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
670 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
671
672 // Install another package with the same uid and no permissions should not cause the UID to
673 // lose permissions.
paulhu86e23eb2019-11-05 18:05:05 +0800674 PackageInfo packageInfo2 = systemPackageInfoWithPermissions();
Chenbo Feng436fe582019-02-25 22:55:58 -0800675 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
676 when(mPackageManager.getPackagesForUid(MOCK_UID1))
677 .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
678 mObserver.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1);
679 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
680 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
681 }
682
683 @Test
684 public void testPackageUninstallBasic() throws Exception {
685 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
686
687 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
688 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
689 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
690
691 when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
692 mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
Chenbo Fenga6817cd2019-03-25 18:13:34 -0700693 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
Chenbo Feng436fe582019-02-25 22:55:58 -0800694 }
695
696 @Test
Lorenzo Colittifc901152019-09-20 11:36:06 +0900697 public void testPackageRemoveThenAdd() throws Exception {
Chenbo Feng436fe582019-02-25 22:55:58 -0800698 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
699
700 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
701 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
702 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
703
Chenbo Feng436fe582019-02-25 22:55:58 -0800704 when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
705 mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
Chenbo Fenga6817cd2019-03-25 18:13:34 -0700706 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
Chenbo Feng436fe582019-02-25 22:55:58 -0800707
708 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
709 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
710 }
711
712 @Test
Lorenzo Colittifc901152019-09-20 11:36:06 +0900713 public void testPackageUpdate() throws Exception {
714 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
715
716 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {});
717 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
718
719 // When updating a package, the broadcast receiver gets two broadcasts (a remove and then an
720 // add), but the observer sees only one callback (an update).
721 setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
722 mObserver.onPackageChanged(MOCK_PACKAGE1, MOCK_UID1);
723 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
724 }
725
726 @Test
Chenbo Feng436fe582019-02-25 22:55:58 -0800727 public void testPackageUninstallWithMultiplePackages() throws Exception {
728 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
729
730 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
731 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
732 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
733
734 // Mock another package with the same uid but different permissions.
paulhu86e23eb2019-11-05 18:05:05 +0800735 PackageInfo packageInfo2 = systemPackageInfoWithPermissions(INTERNET);
Chenbo Feng436fe582019-02-25 22:55:58 -0800736 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
737 when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{
738 MOCK_PACKAGE2});
739
740 mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
741 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
742 }
Chalard Jean506686b2019-05-23 18:30:38 +0900743
744 @Test
745 public void testRealSystemPermission() throws Exception {
746 // Use the real context as this test must ensure the *real* system package holds the
747 // necessary permission.
748 final Context realContext = InstrumentationRegistry.getContext();
749 final PermissionMonitor monitor = new PermissionMonitor(realContext, mNetdService);
750 final PackageManager manager = realContext.getPackageManager();
751 final PackageInfo systemInfo = manager.getPackageInfo(REAL_SYSTEM_PACKAGE_NAME,
752 GET_PERMISSIONS | MATCH_ANY_USER);
753 assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
754 }
Chalard Jean26aa91a2018-03-20 19:13:57 +0900755}