1 /* 2 * Copyright (C) 2017 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 com.android.compatibility.common.util.ShellUtils.runShellCommand; 20 21 import static com.google.common.truth.Truth.assertWithMessage; 22 23 import static org.junit.Assert.assertThrows; 24 import static org.junit.Assert.fail; 25 26 import static java.lang.reflect.Modifier.isFinal; 27 import static java.lang.reflect.Modifier.isPublic; 28 import static java.lang.reflect.Modifier.isStatic; 29 30 import android.annotation.NonNull; 31 import android.annotation.Nullable; 32 import android.app.AppGlobals; 33 import android.content.IIntentReceiver; 34 import android.content.pm.IPackageManager; 35 import android.content.pm.PackageManager; 36 import android.os.Bundle; 37 import android.os.UserHandle; 38 import android.os.UserManager; 39 import android.platform.test.annotations.Postsubmit; 40 import android.util.SparseArray; 41 42 import androidx.test.InstrumentationRegistry; 43 import androidx.test.runner.AndroidJUnit4; 44 45 import com.android.internal.util.HexDump; 46 import com.android.server.pm.PerPackageReadTimeouts.Timeouts; 47 import com.android.server.pm.PerPackageReadTimeouts.VersionCodes; 48 49 import com.google.android.collect.Lists; 50 51 import org.junit.After; 52 import org.junit.Assert; 53 import org.junit.Assume; 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 58 import java.io.File; 59 import java.lang.reflect.Field; 60 import java.lang.reflect.Method; 61 import java.lang.reflect.Type; 62 import java.util.ArrayList; 63 import java.util.Arrays; 64 import java.util.Collections; 65 import java.util.List; 66 import java.util.regex.Pattern; 67 68 // atest PackageManagerServiceTest 69 @Postsubmit 70 @RunWith(AndroidJUnit4.class) 71 public class PackageManagerServiceTest { 72 73 private static final String PACKAGE_NAME = "com.android.server.pm.test.service.server"; 74 75 private static final String TEST_DATA_PATH = "/data/local/tmp/servicestests/"; 76 private static final String TEST_APP_APK = "StubTestApp.apk"; 77 private static final String TEST_PKG_NAME = "com.android.servicestests.apps.stubapp"; 78 79 private IPackageManager mIPackageManager; 80 81 @Before setUp()82 public void setUp() throws Exception { 83 mIPackageManager = AppGlobals.getPackageManager(); 84 } 85 86 @After tearDown()87 public void tearDown() throws Exception { 88 } 89 90 @Test testPackageRemoval()91 public void testPackageRemoval() { 92 class PackageSenderImpl implements PackageSender { 93 public void sendPackageBroadcast(final String action, final String pkg, 94 final Bundle extras, final int flags, final String targetPkg, 95 final IIntentReceiver finishedReceiver, final int[] userIds, 96 int[] instantUserIds, SparseArray<int[]> broadcastAllowList, 97 @Nullable Bundle bOptions) { 98 } 99 100 public void sendPackageAddedForNewUsers(@NonNull Computer snapshot, String packageName, 101 boolean sendBootComplete, boolean includeStopped, int appId, 102 int[] userIds, int[] instantUserIds, int dataLoaderType) { 103 } 104 105 @Override 106 public void notifyPackageAdded(String packageName, int uid) { 107 } 108 109 @Override 110 public void notifyPackageChanged(String packageName, int uid) { 111 112 } 113 114 @Override 115 public void notifyPackageRemoved(String packageName, int uid) { 116 } 117 } 118 119 PackageSenderImpl sender = new PackageSenderImpl(); 120 PackageSetting setting = null; 121 PackageRemovedInfo pri = new PackageRemovedInfo(sender); 122 123 // Initial conditions: nothing there 124 Assert.assertNull(pri.mRemovedUsers); 125 Assert.assertNull(pri.mBroadcastUsers); 126 127 // populateUsers with nothing leaves nothing 128 pri.populateUsers(null, setting); 129 Assert.assertNull(pri.mBroadcastUsers); 130 131 // Create a real (non-null) PackageSetting and confirm that the removed 132 // users are copied properly 133 setting = new PackageSettingBuilder() 134 .setName("name") 135 .setRealName("realName") 136 .setCodePath("codePath") 137 .setLegacyNativeLibraryPathString("legacyNativeLibraryPathString") 138 .setPrimaryCpuAbiString("primaryCpuAbiString") 139 .setSecondaryCpuAbiString("secondaryCpuAbiString") 140 .setCpuAbiOverrideString("cpuAbiOverrideString") 141 .build(); 142 pri.populateUsers(new int[]{ 143 1, 2, 3, 4, 5 144 }, setting); 145 Assert.assertNotNull(pri.mBroadcastUsers); 146 Assert.assertEquals(5, pri.mBroadcastUsers.length); 147 Assert.assertNotNull(pri.mInstantUserIds); 148 Assert.assertEquals(0, pri.mInstantUserIds.length); 149 150 // Exclude a user 151 pri.mBroadcastUsers = null; 152 final int EXCLUDED_USER_ID = 4; 153 setting.setInstantApp(true, EXCLUDED_USER_ID); 154 pri.populateUsers(new int[]{ 155 1, 2, 3, EXCLUDED_USER_ID, 5 156 }, setting); 157 Assert.assertNotNull(pri.mBroadcastUsers); 158 Assert.assertEquals(4, pri.mBroadcastUsers.length); 159 Assert.assertNotNull(pri.mInstantUserIds); 160 Assert.assertEquals(1, pri.mInstantUserIds.length); 161 162 // TODO: test that sendApplicationHiddenForUser() actually fills in 163 // broadcastUsers 164 } 165 166 @Test testPartitions()167 public void testPartitions() { 168 String[] partitions = {"system", "vendor", "odm", "oem", "product", "system_ext"}; 169 String[] appdir = {"app", "priv-app"}; 170 for (int i = 0; i < partitions.length; i++) { 171 final ScanPartition scanPartition = 172 PackageManagerService.SYSTEM_PARTITIONS.get(i); 173 for (int j = 0; j < appdir.length; j++) { 174 File path = new File(String.format("%s/%s/A.apk", partitions[i], appdir[j])); 175 Assert.assertEquals(j == 1 && i != 3, scanPartition.containsPrivApp(path)); 176 177 final int scanFlag = scanPartition.scanFlag; 178 Assert.assertEquals(i == 1, scanFlag == PackageManagerService.SCAN_AS_VENDOR); 179 Assert.assertEquals(i == 2, scanFlag == PackageManagerService.SCAN_AS_ODM); 180 Assert.assertEquals(i == 3, scanFlag == PackageManagerService.SCAN_AS_OEM); 181 Assert.assertEquals(i == 4, scanFlag == PackageManagerService.SCAN_AS_PRODUCT); 182 Assert.assertEquals(i == 5, scanFlag == PackageManagerService.SCAN_AS_SYSTEM_EXT); 183 } 184 } 185 } 186 187 @Test testKnownPackageToString_shouldNotGetUnknown()188 public void testKnownPackageToString_shouldNotGetUnknown() { 189 final List<String> packageNames = new ArrayList<>(); 190 for (int i = 0; i <= KnownPackages.LAST_KNOWN_PACKAGE; i++) { 191 packageNames.add(KnownPackages.knownPackageToString(i)); 192 } 193 assertWithMessage( 194 "The Ids of KnownPackage should be continuous and the string representation " 195 + "should not be unknown.").that( 196 packageNames).containsNoneIn(Lists.newArrayList("Unknown")); 197 } 198 199 @Test testKnownPackage_lastKnownPackageIsTheLast()200 public void testKnownPackage_lastKnownPackageIsTheLast() throws Exception { 201 final List<Integer> knownPackageIds = getKnownPackageIdsList(); 202 assertWithMessage( 203 "The last KnownPackage Id should be assigned to PackageManagerInternal" 204 + ".LAST_KNOWN_PACKAGE.").that( 205 knownPackageIds.get(knownPackageIds.size() - 1)).isEqualTo( 206 KnownPackages.LAST_KNOWN_PACKAGE); 207 } 208 209 @Test testKnownPackage_IdsShouldBeUniqueAndContinuous()210 public void testKnownPackage_IdsShouldBeUniqueAndContinuous() throws Exception { 211 final List<Integer> knownPackageIds = getKnownPackageIdsList(); 212 for (int i = 0, size = knownPackageIds.size(); i < size - 1; i++) { 213 assertWithMessage( 214 "The KnownPackage Ids should be unique and continuous. KnownPackageIds = " 215 + Arrays.toString(knownPackageIds.toArray())).that( 216 knownPackageIds.get(i) + 1).isEqualTo(knownPackageIds.get(i + 1)); 217 } 218 } 219 220 @Test testTimeouts()221 public void testTimeouts() { 222 Timeouts defaults = Timeouts.parse("3600000001:3600000002:3600000003"); 223 Assert.assertEquals(3600000001L, defaults.minTimeUs); 224 Assert.assertEquals(3600000002L, defaults.minPendingTimeUs); 225 Assert.assertEquals(3600000003L, defaults.maxPendingTimeUs); 226 227 Timeouts empty = Timeouts.parse(""); 228 Assert.assertEquals(3600000000L, empty.minTimeUs); 229 Assert.assertEquals(3600000000L, empty.minPendingTimeUs); 230 Assert.assertEquals(3600000000L, empty.maxPendingTimeUs); 231 232 Timeouts partial0 = Timeouts.parse("10000::"); 233 Assert.assertEquals(10000L, partial0.minTimeUs); 234 Assert.assertEquals(3600000000L, partial0.minPendingTimeUs); 235 Assert.assertEquals(3600000000L, partial0.maxPendingTimeUs); 236 237 Timeouts partial1 = Timeouts.parse("10000:10001:"); 238 Assert.assertEquals(10000L, partial1.minTimeUs); 239 Assert.assertEquals(10001L, partial1.minPendingTimeUs); 240 Assert.assertEquals(3600000000L, partial1.maxPendingTimeUs); 241 242 Timeouts fullDefault = Timeouts.parse("3600000000:3600000000:3600000000"); 243 Assert.assertEquals(3600000000L, fullDefault.minTimeUs); 244 Assert.assertEquals(3600000000L, fullDefault.minPendingTimeUs); 245 Assert.assertEquals(3600000000L, fullDefault.maxPendingTimeUs); 246 247 Timeouts full = Timeouts.parse("10000:10001:10002"); 248 Assert.assertEquals(10000L, full.minTimeUs); 249 Assert.assertEquals(10001L, full.minPendingTimeUs); 250 Assert.assertEquals(10002L, full.maxPendingTimeUs); 251 252 Timeouts invalid0 = Timeouts.parse(":10000"); 253 Assert.assertEquals(3600000000L, invalid0.minTimeUs); 254 Assert.assertEquals(3600000000L, invalid0.minPendingTimeUs); 255 Assert.assertEquals(3600000000L, invalid0.maxPendingTimeUs); 256 257 Timeouts invalid1 = Timeouts.parse(":10000::"); 258 Assert.assertEquals(3600000000L, invalid1.minTimeUs); 259 Assert.assertEquals(3600000000L, invalid1.minPendingTimeUs); 260 Assert.assertEquals(3600000000L, invalid1.maxPendingTimeUs); 261 262 Timeouts invalid2 = Timeouts.parse("10000:10001:abcd"); 263 Assert.assertEquals(10000L, invalid2.minTimeUs); 264 Assert.assertEquals(10001L, invalid2.minPendingTimeUs); 265 Assert.assertEquals(3600000000L, invalid2.maxPendingTimeUs); 266 267 Timeouts invalid3 = Timeouts.parse(":10000:"); 268 Assert.assertEquals(3600000000L, invalid3.minTimeUs); 269 Assert.assertEquals(3600000000L, invalid3.minPendingTimeUs); 270 Assert.assertEquals(3600000000L, invalid3.maxPendingTimeUs); 271 272 Timeouts invalid4 = Timeouts.parse("abcd:10001:10002"); 273 Assert.assertEquals(3600000000L, invalid4.minTimeUs); 274 Assert.assertEquals(3600000000L, invalid4.minPendingTimeUs); 275 Assert.assertEquals(3600000000L, invalid4.maxPendingTimeUs); 276 277 Timeouts invalid5 = Timeouts.parse("::1000000000000000000000000"); 278 Assert.assertEquals(3600000000L, invalid5.minTimeUs); 279 Assert.assertEquals(3600000000L, invalid5.minPendingTimeUs); 280 Assert.assertEquals(3600000000L, invalid5.maxPendingTimeUs); 281 282 Timeouts invalid6 = Timeouts.parse("-10000:10001:10002"); 283 Assert.assertEquals(3600000000L, invalid6.minTimeUs); 284 Assert.assertEquals(3600000000L, invalid6.minPendingTimeUs); 285 Assert.assertEquals(3600000000L, invalid6.maxPendingTimeUs); 286 } 287 288 @Test testVersionCodes()289 public void testVersionCodes() { 290 final VersionCodes defaults = VersionCodes.parse(""); 291 Assert.assertEquals(Long.MIN_VALUE, defaults.minVersionCode); 292 Assert.assertEquals(Long.MAX_VALUE, defaults.maxVersionCode); 293 294 VersionCodes single = VersionCodes.parse("191000070"); 295 Assert.assertEquals(191000070, single.minVersionCode); 296 Assert.assertEquals(191000070, single.maxVersionCode); 297 298 VersionCodes single2 = VersionCodes.parse("191000070-191000070"); 299 Assert.assertEquals(191000070, single2.minVersionCode); 300 Assert.assertEquals(191000070, single2.maxVersionCode); 301 302 VersionCodes upto = VersionCodes.parse("-191000070"); 303 Assert.assertEquals(Long.MIN_VALUE, upto.minVersionCode); 304 Assert.assertEquals(191000070, upto.maxVersionCode); 305 306 VersionCodes andabove = VersionCodes.parse("191000070-"); 307 Assert.assertEquals(191000070, andabove.minVersionCode); 308 Assert.assertEquals(Long.MAX_VALUE, andabove.maxVersionCode); 309 310 VersionCodes range = VersionCodes.parse("191000070-201000070"); 311 Assert.assertEquals(191000070, range.minVersionCode); 312 Assert.assertEquals(201000070, range.maxVersionCode); 313 314 VersionCodes invalid0 = VersionCodes.parse("201000070-191000070"); 315 Assert.assertEquals(Long.MIN_VALUE, invalid0.minVersionCode); 316 Assert.assertEquals(Long.MAX_VALUE, invalid0.maxVersionCode); 317 318 VersionCodes invalid1 = VersionCodes.parse("abcd-191000070"); 319 Assert.assertEquals(Long.MIN_VALUE, invalid1.minVersionCode); 320 Assert.assertEquals(191000070, invalid1.maxVersionCode); 321 322 VersionCodes invalid2 = VersionCodes.parse("abcd"); 323 Assert.assertEquals(Long.MIN_VALUE, invalid2.minVersionCode); 324 Assert.assertEquals(Long.MAX_VALUE, invalid2.maxVersionCode); 325 326 VersionCodes invalid3 = VersionCodes.parse("191000070-abcd"); 327 Assert.assertEquals(191000070, invalid3.minVersionCode); 328 Assert.assertEquals(Long.MAX_VALUE, invalid3.maxVersionCode); 329 } 330 331 @Test testPerPackageReadTimeouts()332 public void testPerPackageReadTimeouts() { 333 final String sha256 = "336faefc91bb2dddf9b21829106fbc607b862132fecd273e1b6b3ea55f09d4e1"; 334 final VersionCodes defVCs = VersionCodes.parse(""); 335 final Timeouts defTs = Timeouts.parse("3600000001:3600000002:3600000003"); 336 337 PerPackageReadTimeouts empty = PerPackageReadTimeouts.parse("", defVCs, defTs); 338 Assert.assertNull(empty); 339 340 PerPackageReadTimeouts packageOnly = PerPackageReadTimeouts.parse("package.com", defVCs, 341 defTs); 342 Assert.assertEquals("package.com", packageOnly.packageName); 343 Assert.assertEquals(null, packageOnly.sha256certificate); 344 Assert.assertEquals(Long.MIN_VALUE, packageOnly.versionCodes.minVersionCode); 345 Assert.assertEquals(Long.MAX_VALUE, packageOnly.versionCodes.maxVersionCode); 346 Assert.assertEquals(3600000001L, packageOnly.timeouts.minTimeUs); 347 Assert.assertEquals(3600000002L, packageOnly.timeouts.minPendingTimeUs); 348 Assert.assertEquals(3600000003L, packageOnly.timeouts.maxPendingTimeUs); 349 350 PerPackageReadTimeouts packageHash = PerPackageReadTimeouts.parse( 351 "package.com:" + sha256, defVCs, defTs); 352 Assert.assertEquals("package.com", packageHash.packageName); 353 Assert.assertEquals(sha256, bytesToHexString(packageHash.sha256certificate)); 354 Assert.assertEquals(Long.MIN_VALUE, packageHash.versionCodes.minVersionCode); 355 Assert.assertEquals(Long.MAX_VALUE, packageHash.versionCodes.maxVersionCode); 356 Assert.assertEquals(3600000001L, packageHash.timeouts.minTimeUs); 357 Assert.assertEquals(3600000002L, packageHash.timeouts.minPendingTimeUs); 358 Assert.assertEquals(3600000003L, packageHash.timeouts.maxPendingTimeUs); 359 360 PerPackageReadTimeouts packageVersionCode = PerPackageReadTimeouts.parse( 361 "package.com::191000070", defVCs, defTs); 362 Assert.assertEquals("package.com", packageVersionCode.packageName); 363 Assert.assertEquals(null, packageVersionCode.sha256certificate); 364 Assert.assertEquals(191000070, packageVersionCode.versionCodes.minVersionCode); 365 Assert.assertEquals(191000070, packageVersionCode.versionCodes.maxVersionCode); 366 Assert.assertEquals(3600000001L, packageVersionCode.timeouts.minTimeUs); 367 Assert.assertEquals(3600000002L, packageVersionCode.timeouts.minPendingTimeUs); 368 Assert.assertEquals(3600000003L, packageVersionCode.timeouts.maxPendingTimeUs); 369 370 PerPackageReadTimeouts full = PerPackageReadTimeouts.parse( 371 "package.com:" + sha256 + ":191000070-201000070:10001:10002:10003", defVCs, defTs); 372 Assert.assertEquals("package.com", full.packageName); 373 Assert.assertEquals(sha256, bytesToHexString(full.sha256certificate)); 374 Assert.assertEquals(191000070, full.versionCodes.minVersionCode); 375 Assert.assertEquals(201000070, full.versionCodes.maxVersionCode); 376 Assert.assertEquals(10001L, full.timeouts.minTimeUs); 377 Assert.assertEquals(10002L, full.timeouts.minPendingTimeUs); 378 Assert.assertEquals(10003L, full.timeouts.maxPendingTimeUs); 379 } 380 381 @Test testGetPerPackageReadTimeouts()382 public void testGetPerPackageReadTimeouts() { 383 Assert.assertEquals(0, getPerPackageReadTimeouts(null).length); 384 Assert.assertEquals(0, getPerPackageReadTimeouts("").length); 385 Assert.assertEquals(0, getPerPackageReadTimeouts(",,,,").length); 386 387 final String sha256 = "0fae93f1a7925b4c68bbea80ad3eaa41acfc9bc6f10bf1054f5d93a2bd556093"; 388 389 PerPackageReadTimeouts[] singlePackage = getPerPackageReadTimeouts( 390 "package.com:" + sha256 + ":191000070-201000070:10001:10002:10003"); 391 Assert.assertEquals(1, singlePackage.length); 392 Assert.assertEquals("package.com", singlePackage[0].packageName); 393 Assert.assertEquals(sha256, bytesToHexString(singlePackage[0].sha256certificate)); 394 Assert.assertEquals(191000070, singlePackage[0].versionCodes.minVersionCode); 395 Assert.assertEquals(201000070, singlePackage[0].versionCodes.maxVersionCode); 396 Assert.assertEquals(10001L, singlePackage[0].timeouts.minTimeUs); 397 Assert.assertEquals(10002L, singlePackage[0].timeouts.minPendingTimeUs); 398 Assert.assertEquals(10003L, singlePackage[0].timeouts.maxPendingTimeUs); 399 400 PerPackageReadTimeouts[] multiPackage = getPerPackageReadTimeouts("package.com:" + sha256 401 + ":191000070-201000070:10001:10002:10003,package1.com::123456"); 402 Assert.assertEquals(2, multiPackage.length); 403 Assert.assertEquals("package.com", multiPackage[0].packageName); 404 Assert.assertEquals(sha256, bytesToHexString(multiPackage[0].sha256certificate)); 405 Assert.assertEquals(191000070, multiPackage[0].versionCodes.minVersionCode); 406 Assert.assertEquals(201000070, multiPackage[0].versionCodes.maxVersionCode); 407 Assert.assertEquals(10001L, multiPackage[0].timeouts.minTimeUs); 408 Assert.assertEquals(10002L, multiPackage[0].timeouts.minPendingTimeUs); 409 Assert.assertEquals(10003L, multiPackage[0].timeouts.maxPendingTimeUs); 410 Assert.assertEquals("package1.com", multiPackage[1].packageName); 411 Assert.assertEquals(null, multiPackage[1].sha256certificate); 412 Assert.assertEquals(123456, multiPackage[1].versionCodes.minVersionCode); 413 Assert.assertEquals(123456, multiPackage[1].versionCodes.maxVersionCode); 414 Assert.assertEquals(3600000001L, multiPackage[1].timeouts.minTimeUs); 415 Assert.assertEquals(3600000002L, multiPackage[1].timeouts.minPendingTimeUs); 416 Assert.assertEquals(3600000003L, multiPackage[1].timeouts.maxPendingTimeUs); 417 } 418 419 // Report an error from the Computer structure validation test. flag(String name, String msg)420 private void flag(String name, String msg) { 421 fail(name + " " + msg); 422 } 423 424 // Return a string that identifies a Method. This is not very efficient but it is not 425 // called very often. displayName(Method m)426 private String displayName(Method m) { 427 String r = m.getName(); 428 String p = Arrays.toString(m.getGenericParameterTypes()) 429 .replaceAll("([a-zA-Z0-9]+\\.)+", "") 430 .replace("class ", "") 431 .replaceAll("^\\[", "(") 432 .replaceAll("\\]$", ")"); 433 return r + p; 434 } 435 436 // Match a method to an array of Methods. Matching is on method signature: name and 437 // parameter types. If a method in the declared array matches, return it. Otherwise 438 // return null. matchMethod(Method m, Method[] declared)439 private Method matchMethod(Method m, Method[] declared) { 440 String n = m.getName(); 441 Type[] t = m.getGenericParameterTypes(); 442 for (int i = 0; i < declared.length; i++) { 443 Method l = declared[i]; 444 if (l != null && l.getName().equals(n) 445 && Arrays.equals(l.getGenericParameterTypes(), t)) { 446 Method result = l; 447 // Set the method to null since it has been visited already. 448 declared[i] = null; 449 return result; 450 } 451 } 452 return null; 453 } 454 getPerPackageReadTimeouts(String knownDigestersList)455 private static PerPackageReadTimeouts[] getPerPackageReadTimeouts(String knownDigestersList) { 456 final String defaultTimeouts = "3600000001:3600000002:3600000003"; 457 List<PerPackageReadTimeouts> result = PerPackageReadTimeouts.parseDigestersList( 458 defaultTimeouts, knownDigestersList); 459 if (result == null) { 460 return null; 461 } 462 return result.toArray(new PerPackageReadTimeouts[result.size()]); 463 } 464 bytesToHexString(byte[] bytes)465 private static String bytesToHexString(byte[] bytes) { 466 return HexDump.toHexString(bytes, 0, bytes.length, /*upperCase=*/ false); 467 } 468 getKnownPackageIdsList()469 private List<Integer> getKnownPackageIdsList() throws IllegalAccessException { 470 final ArrayList<Integer> knownPackageIds = new ArrayList<>(); 471 final Field[] allFields = KnownPackages.class.getDeclaredFields(); 472 for (Field field : allFields) { 473 final int modifier = field.getModifiers(); 474 if (isPublic(modifier) && isStatic(modifier) && isFinal(modifier) 475 && Pattern.matches("PACKAGE(_[A-Z]+)+", field.getName())) { 476 knownPackageIds.add(field.getInt(null)); 477 } 478 } 479 Collections.sort(knownPackageIds); 480 return knownPackageIds; 481 } 482 483 @Test testInstallReason_afterUpdate_keepUnchanged()484 public void testInstallReason_afterUpdate_keepUnchanged() throws Exception { 485 final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); 486 try { 487 // Try to install test APK with reason INSTALL_REASON_DEVICE_SETUP 488 runShellCommand("pm install --install-reason 3 " + testApk); 489 assertWithMessage("The install reason of test APK is incorrect.").that( 490 mIPackageManager.getInstallReason(TEST_PKG_NAME, 491 UserHandle.myUserId())).isEqualTo( 492 PackageManager.INSTALL_REASON_DEVICE_SETUP); 493 494 // Try to update test APK with different reason INSTALL_REASON_USER 495 runShellCommand("pm install --install-reason 4 " + testApk); 496 assertWithMessage("The install reason should keep unchanged after update.").that( 497 mIPackageManager.getInstallReason(TEST_PKG_NAME, 498 UserHandle.myUserId())).isEqualTo( 499 PackageManager.INSTALL_REASON_DEVICE_SETUP); 500 } finally { 501 runShellCommand("pm uninstall " + TEST_PKG_NAME); 502 } 503 } 504 505 @Test testInstallReason_userRemainsUninstalled_keepUnknown()506 public void testInstallReason_userRemainsUninstalled_keepUnknown() throws Exception { 507 Assume.assumeTrue(UserManager.supportsMultipleUsers()); 508 final UserManager um = UserManager.get( 509 InstrumentationRegistry.getInstrumentation().getContext()); 510 final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); 511 int userId = UserHandle.USER_NULL; 512 try { 513 // Try to install test APK with reason INSTALL_REASON_DEVICE_SETUP 514 runShellCommand("pm install --install-reason 3 " + testApk); 515 assertWithMessage("The install reason of test APK is incorrect.").that( 516 mIPackageManager.getInstallReason(TEST_PKG_NAME, 517 UserHandle.myUserId())).isEqualTo( 518 PackageManager.INSTALL_REASON_DEVICE_SETUP); 519 520 // Create and start the 2nd user. 521 userId = um.createUser("Test User", 0 /* flags */).getUserHandle().getIdentifier(); 522 runShellCommand("am start-user -w " + userId); 523 // Since the test APK isn't installed on the 2nd user, the reason should be unknown. 524 assertWithMessage("The test APK should not be installed in the 2nd user").that( 525 mIPackageManager.getPackageInfo(TEST_PKG_NAME, 0 /* flags */, userId)).isNull(); 526 assertWithMessage("The install reason in 2nd user should be unknown.").that( 527 mIPackageManager.getInstallReason(TEST_PKG_NAME, userId)).isEqualTo( 528 PackageManager.INSTALL_REASON_UNKNOWN); 529 } finally { 530 runShellCommand("pm uninstall " + TEST_PKG_NAME); 531 if (userId != UserHandle.USER_NULL) { 532 um.removeUser(userId); 533 } 534 } 535 } 536 537 @Test testInstallReason_installForAllUsers_sameReason()538 public void testInstallReason_installForAllUsers_sameReason() throws Exception { 539 Assume.assumeTrue(UserManager.supportsMultipleUsers()); 540 final UserManager um = UserManager.get( 541 InstrumentationRegistry.getInstrumentation().getContext()); 542 final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); 543 int userId = UserHandle.USER_NULL; 544 try { 545 // Create and start the 2nd user. 546 userId = um.createUser("Test User", 0 /* flags */).getUserHandle().getIdentifier(); 547 runShellCommand("am start-user -w " + userId); 548 549 // Try to install test APK to all users with reason INSTALL_REASON_DEVICE_SETUP 550 runShellCommand("pm install --install-reason 3 " + testApk); 551 assertWithMessage("The install reason is inconsistent across users.").that( 552 mIPackageManager.getInstallReason(TEST_PKG_NAME, 553 UserHandle.myUserId())).isEqualTo( 554 mIPackageManager.getInstallReason(TEST_PKG_NAME, userId)); 555 } finally { 556 runShellCommand("pm uninstall " + TEST_PKG_NAME); 557 if (userId != UserHandle.USER_NULL) { 558 um.removeUser(userId); 559 } 560 } 561 } 562 563 @Test testInstallReason_installSeparately_withSeparatedReason()564 public void testInstallReason_installSeparately_withSeparatedReason() throws Exception { 565 Assume.assumeTrue(UserManager.supportsMultipleUsers()); 566 final UserManager um = UserManager.get( 567 InstrumentationRegistry.getInstrumentation().getContext()); 568 final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); 569 int userId = UserHandle.USER_NULL; 570 try { 571 // Create and start the 2nd user. 572 userId = um.createUser("Test User", 0 /* flags */).getUserHandle().getIdentifier(); 573 runShellCommand("am start-user -w " + userId); 574 575 // Try to install test APK on the current user with reason INSTALL_REASON_DEVICE_SETUP 576 runShellCommand("pm install --user cur --install-reason 3 " + testApk); 577 assertWithMessage("The install reason on the current user is incorrect.").that( 578 mIPackageManager.getInstallReason(TEST_PKG_NAME, 579 UserHandle.myUserId())).isEqualTo( 580 PackageManager.INSTALL_REASON_DEVICE_SETUP); 581 582 // Try to install test APK on the 2nd user with reason INSTALL_REASON_USER 583 runShellCommand("pm install --user " + userId + " --install-reason 4 " + testApk); 584 assertWithMessage("The install reason on the 2nd user is incorrect.").that( 585 mIPackageManager.getInstallReason(TEST_PKG_NAME, userId)).isEqualTo( 586 PackageManager.INSTALL_REASON_USER); 587 } finally { 588 runShellCommand("pm uninstall " + TEST_PKG_NAME); 589 if (userId != UserHandle.USER_NULL) { 590 um.removeUser(userId); 591 } 592 } 593 } 594 595 @Test testSetSplashScreenTheme_samePackage_succeeds()596 public void testSetSplashScreenTheme_samePackage_succeeds() throws Exception { 597 mIPackageManager.setSplashScreenTheme(PACKAGE_NAME, null /* themeName */, 598 UserHandle.myUserId()); 599 // Invoking setSplashScreenTheme on the same package shouldn't get any exception. 600 } 601 602 @Test testSetSplashScreenTheme_differentPackage_fails()603 public void testSetSplashScreenTheme_differentPackage_fails() throws Exception { 604 final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); 605 try { 606 runShellCommand("pm install " + testApk); 607 mIPackageManager.setSplashScreenTheme(TEST_PKG_NAME, null /* themeName */, 608 UserHandle.myUserId()); 609 fail("setSplashScreenTheme did not throw SecurityException as expected"); 610 } catch (SecurityException e) { 611 // expected 612 } finally { 613 runShellCommand("pm uninstall " + TEST_PKG_NAME); 614 } 615 } 616 617 @Test testSetUserMinAspectRatio_samePackage_succeeds()618 public void testSetUserMinAspectRatio_samePackage_succeeds() throws Exception { 619 mIPackageManager.setUserMinAspectRatio(PACKAGE_NAME, UserHandle.myUserId(), 620 PackageManager.USER_MIN_ASPECT_RATIO_UNSET); 621 // Invoking setUserMinAspectRatio on the same package shouldn't get any exception. 622 } 623 624 @Test testSetUserMinAspectRatio_differentPackage_fails()625 public void testSetUserMinAspectRatio_differentPackage_fails() { 626 final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); 627 runShellCommand("pm install " + testApk); 628 assertThrows(SecurityException.class, () -> { 629 mIPackageManager.setUserMinAspectRatio(TEST_PKG_NAME, UserHandle.myUserId(), 630 PackageManager.USER_MIN_ASPECT_RATIO_UNSET); 631 }); 632 runShellCommand("pm uninstall " + TEST_PKG_NAME); 633 } 634 } 635