1 /*
2  * Copyright (C) 2019 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.pm;
18 
19 import static android.os.UserManager.USER_TYPE_FULL_GUEST;
20 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
21 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
22 
23 import static com.android.server.pm.UserSystemPackageInstaller.PACKAGE_WHITELIST_MODE_PROP;
24 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT;
25 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE;
26 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE;
27 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA;
28 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST;
29 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM;
30 import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_LOG;
31 
32 import static org.junit.Assert.assertEquals;
33 import static org.junit.Assert.assertFalse;
34 import static org.junit.Assert.assertNotNull;
35 import static org.junit.Assert.assertTrue;
36 import static org.junit.Assert.fail;
37 
38 import android.app.PropertyInvalidatedCache;
39 import android.content.Context;
40 import android.content.pm.PackageInfo;
41 import android.content.pm.PackageManager;
42 import android.content.pm.UserInfo;
43 import android.os.Looper;
44 import android.os.SystemProperties;
45 import android.os.UserManager;
46 import android.platform.test.annotations.Postsubmit;
47 import android.support.test.uiautomator.UiDevice;
48 import android.util.ArrayMap;
49 import android.util.ArraySet;
50 import android.util.Log;
51 
52 import androidx.test.InstrumentationRegistry;
53 import androidx.test.filters.MediumTest;
54 import androidx.test.runner.AndroidJUnit4;
55 
56 import com.android.server.LocalServices;
57 import com.android.server.SystemConfig;
58 import com.android.server.pm.parsing.pkg.PackageImpl;
59 import com.android.server.pm.parsing.pkg.ParsedPackage;
60 import com.android.server.pm.pkg.AndroidPackage;
61 
62 import org.junit.After;
63 import org.junit.Before;
64 import org.junit.Test;
65 import org.junit.runner.RunWith;
66 
67 import java.io.IOException;
68 import java.util.ArrayList;
69 import java.util.Arrays;
70 import java.util.List;
71 import java.util.Set;
72 
73 /**
74  * Tests for UserSystemPackageInstaller.
75  *
76  * <p>Run with:<pre>
77  * atest com.android.server.pm.UserSystemPackageInstallerTest
78  * </pre>
79  */
80 @Postsubmit
81 @RunWith(AndroidJUnit4.class)
82 @MediumTest
83 public class UserSystemPackageInstallerTest {
84     private static final String TAG = "UserSystemPackageInstallerTest";
85 
86     private UserSystemPackageInstaller mUserSystemPackageInstaller;
87 
88     private Context mContext;
89 
90     /** Any users created during this test, for them to be removed when it's done. */
91     private final List<Integer> mRemoveUsers = new ArrayList<>();
92     /** Original value of PACKAGE_WHITELIST_MODE_PROP before the test, to reset at end. */
93     private final int mOriginalWhitelistMode = SystemProperties.getInt(
94             PACKAGE_WHITELIST_MODE_PROP, USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT);
95 
96     @Before
setup()97     public void setup() {
98         // Currently UserManagerService cannot be instantiated twice inside a VM without a cleanup
99         // TODO: Remove once UMS supports proper dependency injection
100         if (Looper.myLooper() == null) {
101             Looper.prepare();
102         }
103         // Disable binder caches in this process.
104         PropertyInvalidatedCache.disableForTestMode();
105 
106         LocalServices.removeServiceForTest(UserManagerInternal.class);
107         UserManagerService ums = new UserManagerService(InstrumentationRegistry.getContext());
108 
109         ArrayMap<String, UserTypeDetails> userTypes = UserTypeFactory.getUserTypes();
110         mUserSystemPackageInstaller = new UserSystemPackageInstaller(ums, userTypes);
111         mContext = InstrumentationRegistry.getTargetContext();
112     }
113 
114     @After
tearDown()115     public void tearDown() {
116         UserManager um = UserManager.get(mContext);
117         for (int userId : mRemoveUsers) {
118             um.removeUser(userId);
119         }
120         setUserTypePackageWhitelistMode(mOriginalWhitelistMode);
121     }
122 
123     /**
124      * Subclass of SystemConfig without running the constructor.
125      */
126     private class SystemConfigTestClass extends SystemConfig {
SystemConfigTestClass(boolean readPermissions)127         SystemConfigTestClass(boolean readPermissions) {
128             super(readPermissions);
129         }
130     }
131 
132     /**
133      * Test that determineWhitelistedPackagesForUserTypes reads SystemConfig information properly.
134      */
135     @Test
testDetermineWhitelistedPackagesForUserTypes()136     public void testDetermineWhitelistedPackagesForUserTypes() {
137         SystemConfig sysConfig = new SystemConfigTestClass(false) {
138             @Override
139             public ArrayMap<String, Set<String>> getAndClearPackageToUserTypeWhitelist() {
140                 ArrayMap<String, Set<String>> r = new ArrayMap<>();
141                 r.put("com.android.package1", new ArraySet<>(Arrays.asList(
142                         "PROFILE", "SYSTEM", USER_TYPE_FULL_GUEST, "invalid-garbage1")));
143                 r.put("com.android.package2", new ArraySet<>(Arrays.asList(
144                         USER_TYPE_PROFILE_MANAGED)));
145                 r.put("com.android.package3", new ArraySet<>(Arrays.asList("FULL")));
146                 return r;
147             }
148 
149             @Override
150             public ArrayMap<String, Set<String>> getAndClearPackageToUserTypeBlacklist() {
151                 ArrayMap<String, Set<String>> r = new ArrayMap<>();
152                 r.put("com.android.package1", new ArraySet<>(Arrays.asList(
153                         USER_TYPE_PROFILE_MANAGED, "invalid-garbage2")));
154                 // com.android.package2 has nothing denylisted
155                 r.put("com.android.package3", new ArraySet<>(Arrays.asList("SYSTEM")));
156                 return r;
157             }
158         };
159 
160         final ArrayMap<String, UserTypeDetails> userTypes = UserTypeFactory.getUserTypes();
161         // Determine the expected userTypeBitSets based on getUserTypeMask.
162         long expectedUserTypeBitSet1 = 0;
163         expectedUserTypeBitSet1
164                 |= mUserSystemPackageInstaller.getUserTypeMask(USER_TYPE_FULL_GUEST);
165         for (int i = 0; i < userTypes.size(); i++) {
166             final String userType = userTypes.keyAt(i);
167             final UserTypeDetails details = userTypes.valueAt(i);
168             if (details.isSystem() || details.isProfile()) {
169                 expectedUserTypeBitSet1 |= mUserSystemPackageInstaller.getUserTypeMask(userType);
170             }
171         }
172         expectedUserTypeBitSet1
173                 &= ~mUserSystemPackageInstaller.getUserTypeMask(USER_TYPE_PROFILE_MANAGED);
174 
175         final long expectedUserTypeBitSet2 =
176                 mUserSystemPackageInstaller.getUserTypeMask(USER_TYPE_PROFILE_MANAGED);
177 
178         long expectedUserTypeBitSet3 = 0;
179         for (int i = 0; i < userTypes.size(); i++) {
180             final String userType = userTypes.keyAt(i);
181             final UserTypeDetails details = userTypes.valueAt(i);
182             if (details.isFull() && !details.isSystem()) {
183                 expectedUserTypeBitSet3 |= mUserSystemPackageInstaller.getUserTypeMask(userType);
184             }
185         }
186 
187         final ArrayMap<String, Long> expectedOutput = getNewPackageToWhitelistedBitSetMap();
188         expectedOutput.put("com.android.package1", expectedUserTypeBitSet1);
189         expectedOutput.put("com.android.package2", expectedUserTypeBitSet2);
190         expectedOutput.put("com.android.package3", expectedUserTypeBitSet3);
191 
192         final ArrayMap<String, Long> actualOutput =
193                 mUserSystemPackageInstaller.determineWhitelistedPackagesForUserTypes(sysConfig);
194 
195         assertEquals("Incorrect package-to-user mapping.", expectedOutput, actualOutput);
196     }
197 
198     /**
199      * Test that determineWhitelistedPackagesForUserTypes does not include packages that were never
200      * allowlisted properly, but does include packages that were allowlisted but then denylisted.
201      */
202     @Test
testDetermineWhitelistedPackagesForUserTypes_noNetWhitelisting()203     public void testDetermineWhitelistedPackagesForUserTypes_noNetWhitelisting() {
204         SystemConfig sysConfig = new SystemConfigTestClass(false) {
205             @Override
206             public ArrayMap<String, Set<String>> getAndClearPackageToUserTypeWhitelist() {
207                 ArrayMap<String, Set<String>> r = new ArrayMap<>();
208                 r.put("com.android.package1", new ArraySet<>(Arrays.asList("invalid1")));
209                 // com.android.package2 has no allowlisting
210                 r.put("com.android.package3", new ArraySet<>(Arrays.asList("PROFILE", "FULL")));
211                 r.put("com.android.package4", new ArraySet<>(Arrays.asList("PROFILE")));
212                 r.put("com.android.package5", new ArraySet<>());
213                 // com.android.package6 has no allowlisting
214                 return r;
215             }
216 
217             @Override
218             public ArrayMap<String, Set<String>> getAndClearPackageToUserTypeBlacklist() {
219                 ArrayMap<String, Set<String>> r = new ArrayMap<>();
220                 // com.android.package1 has no denylisting
221                 r.put("com.android.package2", new ArraySet<>(Arrays.asList("FULL")));
222                 r.put("com.android.package3", new ArraySet<>(Arrays.asList("PROFILE", "FULL")));
223                 r.put("com.android.package4", new ArraySet<>(Arrays.asList("PROFILE", "invalid4")));
224                 // com.android.package5 has no denylisting
225                 r.put("com.android.package6", new ArraySet<>(Arrays.asList("invalid6")));
226                 return r;
227             }
228         };
229 
230         final ArrayMap<String, Long> expectedOutput = getNewPackageToWhitelistedBitSetMap();
231         expectedOutput.put("com.android.package2", 0L);
232         expectedOutput.put("com.android.package3", 0L);
233         expectedOutput.put("com.android.package4", 0L);
234 
235         final ArrayMap<String, Long> actualOutput =
236                 mUserSystemPackageInstaller.determineWhitelistedPackagesForUserTypes(sysConfig);
237 
238         assertEquals("Incorrect package-to-user mapping.", expectedOutput, actualOutput);
239     }
240 
241     /**
242      * Tests that shouldInstallPackage correctly determines which packages should be installed.
243      */
244     @Test
testShouldInstallPackage()245     public void testShouldInstallPackage() {
246         final String packageName1 = "pkg1"; // allowlisted
247         final String packageName2 = "pkg2"; // allowlisted and denylisted
248         final String packageName3 = "pkg3"; // allowlisted for a different user type
249         final String packageName4 = "pkg4"; // not allowlisted nor denylisted at all
250 
251         // Allowlist: user type bitset for each pkg (for the test, all that matters is 0 vs non-0).
252         final ArrayMap<String, Long> pkgBitSetMap = new ArrayMap<>();
253         pkgBitSetMap.put(packageName1, 0b01L);
254         pkgBitSetMap.put(packageName2, 0L);
255         pkgBitSetMap.put(packageName3, 0b10L);
256 
257         // Allowlist of pkgs for this specific user, i.e. subset of pkgBitSetMap for this user.
258         final Set<String> userWhitelist = new ArraySet<>();
259         userWhitelist.add(packageName1);
260 
261         final AndroidPackage pkg1 = ((ParsedPackage) PackageImpl.forTesting(packageName1)
262                 .hideAsParsed()).hideAsFinal();
263         final AndroidPackage pkg2 = ((ParsedPackage) PackageImpl.forTesting(packageName2)
264                 .hideAsParsed()).hideAsFinal();
265         final AndroidPackage pkg3 = ((ParsedPackage) PackageImpl.forTesting(packageName3)
266                 .hideAsParsed()).hideAsFinal();
267         final AndroidPackage pkg4 = ((ParsedPackage) PackageImpl.forTesting(packageName4)
268                 .hideAsParsed()).hideAsFinal();
269 
270         // No implicit allowlist, so only install pkg1.
271         boolean implicit = false;
272         assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
273                 pkg1, pkgBitSetMap, userWhitelist, implicit));
274         assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
275                 pkg2, pkgBitSetMap, userWhitelist, implicit));
276         assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
277                 pkg3, pkgBitSetMap, userWhitelist, implicit));
278         assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
279                 pkg4, pkgBitSetMap, userWhitelist, implicit));
280 
281         // Use implicit allowlist, so install pkg1 and pkg4
282         implicit = true;
283         assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
284                 pkg1, pkgBitSetMap, userWhitelist, implicit));
285         assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
286                 pkg2, pkgBitSetMap, userWhitelist, implicit));
287         assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
288                 pkg3, pkgBitSetMap, userWhitelist, implicit));
289         assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
290                 pkg4, pkgBitSetMap, userWhitelist, implicit));
291     }
292 
293     /**
294      * Tests that getWhitelistedPackagesForUserType works properly, assuming that
295      * mWhitelistedPackagesForUserTypes (i.e. determineWhitelistedPackagesForUserTypes) is correct.
296      */
297     @Test
testGetWhitelistedPackagesForUserType()298     public void testGetWhitelistedPackagesForUserType() {
299         final String[] sortedUserTypes = new String[]{"type_a", "type_b", "type_c", "type_d"};
300         final String nameOfTypeA = sortedUserTypes[0];
301         final String nameOfTypeB = sortedUserTypes[1];
302         final String nameOfTypeC = sortedUserTypes[2];
303         final long maskOfTypeA = 0b0001L;
304         final long maskOfTypeC = 0b0100L;
305 
306         final String packageName1 = "pkg1"; // allowlisted for user type A
307         final String packageName2 = "pkg2"; // denylisted whenever allowlisted
308         final String packageName3 = "pkg3"; // allowlisted for user type C
309         final String packageName4 = "pkg4"; // allowlisted for user type A
310 
311         final ArrayMap<String, Long> pkgBitSetMap = new ArrayMap<>(); // Allowlist: bitset per pkg
312         pkgBitSetMap.put(packageName1, maskOfTypeA);
313         pkgBitSetMap.put(packageName2, 0L);
314         pkgBitSetMap.put(packageName3, maskOfTypeC);
315         pkgBitSetMap.put(packageName4, maskOfTypeA);
316 
317         UserSystemPackageInstaller uspi =
318                 new UserSystemPackageInstaller(null, pkgBitSetMap, sortedUserTypes);
319 
320         Set<String> output = uspi.getWhitelistedPackagesForUserType(nameOfTypeA);
321         assertEquals("Whitelist for FULL is the wrong size", 2, output.size());
322         assertTrue("Whitelist for A doesn't contain pkg1", output.contains(packageName1));
323         assertTrue("Whitelist for A doesn't contain pkg4", output.contains(packageName4));
324 
325         output = uspi.getWhitelistedPackagesForUserType(nameOfTypeB);
326         assertEquals("Whitelist for B is the wrong size", 0, output.size());
327 
328         output = uspi.getWhitelistedPackagesForUserType(nameOfTypeC);
329         assertEquals("Whitelist for C is the wrong size", 1, output.size());
330         assertTrue("Whitelist for C doesn't contain pkg1", output.contains(packageName3));
331     }
332 
333     /**
334      * Test that a newly created FULL user has the expected system packages.
335      *
336      * Assumes that SystemConfig and UserManagerService.determineWhitelistedPackagesForUserTypes
337      * work correctly (they are tested separately).
338      */
339     @Test
testPackagesForCreateUser_full()340     public void testPackagesForCreateUser_full() {
341         final String userTypeToCreate = USER_TYPE_FULL_SECONDARY;
342         final long userTypeMask = mUserSystemPackageInstaller.getUserTypeMask(userTypeToCreate);
343         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
344         PackageManager pm = mContext.getPackageManager();
345 
346         final SystemConfig sysConfig = new SystemConfigTestClass(true);
347         final ArrayMap<String, Long> packageMap =
348                 mUserSystemPackageInstaller.determineWhitelistedPackagesForUserTypes(sysConfig);
349         final Set<String> expectedPackages = new ArraySet<>(packageMap.size());
350         for (int i = 0; i < packageMap.size(); i++) {
351             if ((userTypeMask & packageMap.valueAt(i)) != 0) {
352                 expectedPackages.add(packageMap.keyAt(i));
353             }
354         }
355 
356         final UserManager um = UserManager.get(mContext);
357         final UserInfo user = um.createUser("Test User", userTypeToCreate, 0);
358         assertNotNull(user);
359         mRemoveUsers.add(user.id);
360 
361         final List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser(
362                 PackageManager.MATCH_SYSTEM_ONLY
363                         | PackageManager.MATCH_DISABLED_COMPONENTS
364                         | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS,
365                 user.id);
366         final Set<String> actualPackages = new ArraySet<>(packageInfos.size());
367         for (PackageInfo p : packageInfos) {
368             actualPackages.add(p.packageName);
369         }
370 
371         // Add static overlays to expectedPackages since they are not (supposed to be)
372         // in the allowlist but they should be installed if their target is.
373         for (PackageInfo p : packageInfos) {
374             if (p.isStaticOverlayPackage() && expectedPackages.contains(p.overlayTarget)) {
375                 expectedPackages.add(p.packageName);
376             }
377         }
378         checkPackageDifferences(expectedPackages, actualPackages);
379     }
380 
381     /**
382      * Test that static overlay package not in allowlist should be installed for all users
383      * based on their targets, in Explicit mode.
384      */
385     @Test
testInstallOverlayPackagesExplicitMode()386     public void testInstallOverlayPackagesExplicitMode() {
387         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
388 
389         final String[] userTypes = new String[]{"type"};
390         final long maskOfType = 0b0001L;
391 
392         final String packageName1 = "whitelistedPkg";
393         final String packageName2 = "nonWhitelistedPkg";
394         final String overlayName1 = String.format("%s.auto_generated_rro_product__", packageName1);
395         final String overlayName2 = String.format("%s.auto_generated_rro_product__", packageName2);
396         final String overlayName3 = String.format("%s.non_static_overlay", packageName1);
397 
398         // Static overlay for allowlisted package1 -> should be installed, like package1
399         final AndroidPackage overlayPackage1 = ((ParsedPackage) PackageImpl.forTesting(overlayName1)
400                 .setResourceOverlay(true)
401                 .setOverlayIsStatic(true)
402                 .setOverlayTarget(packageName1)
403                 .hideAsParsed())
404                 .hideAsFinal();
405 
406         // Static overlay for non-allowlisted package2 -> should not be installed, like package2
407         final AndroidPackage overlayPackage2 = ((ParsedPackage) PackageImpl.forTesting(overlayName2)
408                 .setResourceOverlay(true)
409                 .setOverlayIsStatic(true)
410                 .setOverlayTarget(packageName2)
411                 .hideAsParsed())
412                 .hideAsFinal();
413 
414         // Non-static overlay for package1 -> not explicitly allowlisted, so shouldn't be installed
415         final AndroidPackage overlayPackage3 = ((ParsedPackage) PackageImpl.forTesting(overlayName3)
416                 .setResourceOverlay(true)
417                 .setOverlayIsStatic(false) // non-static
418                 .setOverlayTarget(packageName1)
419                 .hideAsParsed())
420                 .hideAsFinal();
421 
422         final ArrayMap<String, Long> userTypeWhitelist = new ArrayMap<>();
423         userTypeWhitelist.put(packageName1, maskOfType);
424 
425         final Set<String> userWhitelist = new ArraySet<>();
426         userWhitelist.add(packageName1);
427 
428         boolean implicit = false;
429         assertTrue("Should install static overlay for package1", UserSystemPackageInstaller
430                 .shouldInstallPackage(overlayPackage1, userTypeWhitelist, userWhitelist, implicit));
431         assertFalse("Should not install static overlay for package2", UserSystemPackageInstaller
432                 .shouldInstallPackage(overlayPackage2, userTypeWhitelist, userWhitelist, implicit));
433         assertFalse("Should not install regular overlay for package1", UserSystemPackageInstaller
434                 .shouldInstallPackage(overlayPackage3, userTypeWhitelist, userWhitelist, implicit));
435     }
436 
437     /** Asserts that actual is a subset of expected. */
checkPackageDifferences(Set<String> expected, Set<String> actual)438     private void checkPackageDifferences(Set<String> expected, Set<String> actual) {
439         final Set<String> uniqueToExpected = new ArraySet<>(expected);
440         uniqueToExpected.removeAll(actual);
441         final Set<String> uniqueToActual = new ArraySet<>(actual);
442         uniqueToActual.removeAll(expected);
443 
444         Log.v(TAG, "Expected list uniquely has " + uniqueToExpected);
445         Log.v(TAG, "Actual list uniquely has " + uniqueToActual);
446 
447         assertTrue("User's system packages includes non-whitelisted packages: " + uniqueToActual,
448                 uniqueToActual.isEmpty());
449     }
450 
451     /**
452      * Test that setEnableUserTypePackageWhitelist() has the correct effect.
453      */
454     @Test
testSetWhitelistEnabledMode()455     public void testSetWhitelistEnabledMode() {
456         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE);
457         assertFalse(mUserSystemPackageInstaller.isLogMode());
458         assertFalse(mUserSystemPackageInstaller.isEnforceMode());
459         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
460         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
461         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
462 
463         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_LOG);
464         assertTrue(mUserSystemPackageInstaller.isLogMode());
465         assertFalse(mUserSystemPackageInstaller.isEnforceMode());
466         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
467         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
468         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
469 
470         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
471         assertFalse(mUserSystemPackageInstaller.isLogMode());
472         assertTrue(mUserSystemPackageInstaller.isEnforceMode());
473         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
474         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
475         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
476 
477         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST);
478         assertFalse(mUserSystemPackageInstaller.isLogMode());
479         assertFalse(mUserSystemPackageInstaller.isEnforceMode());
480         assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistMode());
481         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
482         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
483 
484         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM);
485         assertFalse(mUserSystemPackageInstaller.isLogMode());
486         assertFalse(mUserSystemPackageInstaller.isEnforceMode());
487         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
488         assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
489         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
490 
491         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA);
492         assertFalse(mUserSystemPackageInstaller.isLogMode());
493         assertFalse(mUserSystemPackageInstaller.isEnforceMode());
494         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
495         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
496         assertTrue(mUserSystemPackageInstaller.isIgnoreOtaMode());
497 
498         setUserTypePackageWhitelistMode(
499                 USER_TYPE_PACKAGE_WHITELIST_MODE_LOG | USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
500         assertTrue(mUserSystemPackageInstaller.isLogMode());
501         assertTrue(mUserSystemPackageInstaller.isEnforceMode());
502         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
503         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
504         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
505 
506         setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST
507                 | USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
508         assertFalse(mUserSystemPackageInstaller.isLogMode());
509         assertTrue(mUserSystemPackageInstaller.isEnforceMode());
510         assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistMode());
511         assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
512         assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
513     }
514 
515     /** Sets the allowlist mode to the desired value via adb's setprop. */
setUserTypePackageWhitelistMode(int mode)516     private void setUserTypePackageWhitelistMode(int mode) {
517         UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
518         try {
519             String result = uiDevice.executeShellCommand(String.format("setprop %s %d",
520                     PACKAGE_WHITELIST_MODE_PROP, mode));
521             assertFalse("Failed to set sysprop " + PACKAGE_WHITELIST_MODE_PROP + ": " + result,
522                     result != null && result.contains("Failed"));
523         } catch (IOException e) {
524             fail("Failed to set sysprop " + PACKAGE_WHITELIST_MODE_PROP + ":\n" + e);
525         }
526     }
527 
528     /** @see UserSystemPackageInstaller#mWhitelistedPackagesForUserTypes */
getNewPackageToWhitelistedBitSetMap()529     private ArrayMap<String, Long> getNewPackageToWhitelistedBitSetMap() {
530         final ArrayMap<String, Long> pkgBitSetMap = new ArrayMap<>();
531         // "android" is always treated as allowlisted for all types, regardless of the xml file.
532         pkgBitSetMap.put("android", ~0L);
533         return pkgBitSetMap;
534     }
535 }
536