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 android.content.pm.cts; 18 19 import static android.content.Context.RECEIVER_EXPORTED; 20 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256; 21 import static android.content.pm.Checksum.TYPE_WHOLE_MERKLE_ROOT_4K_SHA256; 22 import static android.content.pm.Flags.FLAG_SDK_LIB_INDEPENDENCE; 23 import static android.content.pm.PackageInstaller.DATA_LOADER_TYPE_INCREMENTAL; 24 import static android.content.pm.PackageInstaller.DATA_LOADER_TYPE_NONE; 25 import static android.content.pm.PackageInstaller.DATA_LOADER_TYPE_STREAMING; 26 import static android.content.pm.PackageInstaller.EXTRA_DATA_LOADER_TYPE; 27 import static android.content.pm.PackageInstaller.EXTRA_SESSION_ID; 28 import static android.content.pm.PackageInstaller.LOCATION_DATA_APP; 29 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID; 30 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ROOT_HASH; 31 import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES; 32 import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES; 33 import static android.content.pm.PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES; 34 import static android.content.pm.PackageManager.VERIFICATION_ALLOW; 35 import static android.content.pm.PackageManager.VERIFICATION_REJECT; 36 37 import static com.google.common.truth.Truth.assertThat; 38 39 import static org.junit.Assert.assertEquals; 40 import static org.junit.Assert.assertFalse; 41 import static org.junit.Assert.assertNotEquals; 42 import static org.junit.Assert.assertNotNull; 43 import static org.junit.Assert.assertNull; 44 import static org.junit.Assert.assertTrue; 45 import static org.junit.Assume.assumeFalse; 46 import static org.junit.Assume.assumeTrue; 47 import static org.testng.Assert.assertThrows; 48 import static org.testng.Assert.expectThrows; 49 50 import android.Manifest; 51 import android.app.UiAutomation; 52 import android.app.usage.StorageStats; 53 import android.app.usage.StorageStatsManager; 54 import android.content.BroadcastReceiver; 55 import android.content.ComponentName; 56 import android.content.Context; 57 import android.content.IIntentReceiver; 58 import android.content.IIntentSender; 59 import android.content.Intent; 60 import android.content.IntentFilter; 61 import android.content.IntentSender; 62 import android.content.pm.ApkChecksum; 63 import android.content.pm.ApplicationInfo; 64 import android.content.pm.DataLoaderParams; 65 import android.content.pm.Flags; 66 import android.content.pm.PackageInfo; 67 import android.content.pm.PackageInstaller; 68 import android.content.pm.PackageInstaller.SessionParams; 69 import android.content.pm.PackageManager; 70 import android.content.pm.ResolveInfo; 71 import android.content.pm.SharedLibraryInfo; 72 import android.content.pm.Signature; 73 import android.content.pm.SigningInfo; 74 import android.content.pm.cts.util.AbandonAllPackageSessionsRule; 75 import android.os.Bundle; 76 import android.os.IBinder; 77 import android.os.ParcelFileDescriptor; 78 import android.os.Process; 79 import android.os.RemoteException; 80 import android.os.UserHandle; 81 import android.os.storage.StorageManager; 82 import android.platform.test.annotations.AppModeFull; 83 import android.platform.test.annotations.AppModeNonSdkSandbox; 84 import android.platform.test.annotations.RequiresFlagsDisabled; 85 import android.platform.test.annotations.RequiresFlagsEnabled; 86 import android.platform.test.flag.junit.CheckFlagsRule; 87 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 88 import android.util.PackageUtils; 89 90 import androidx.test.InstrumentationRegistry; 91 import androidx.test.filters.LargeTest; 92 93 import com.android.compatibility.common.util.SystemUtil; 94 import com.android.internal.util.ConcurrentUtils; 95 import com.android.internal.util.HexDump; 96 97 import libcore.util.HexEncoding; 98 99 import org.junit.AfterClass; 100 import org.junit.Before; 101 import org.junit.BeforeClass; 102 import org.junit.Rule; 103 import org.junit.Test; 104 import org.junit.runner.RunWith; 105 import org.junit.runners.Parameterized; 106 import org.junit.runners.Parameterized.Parameter; 107 import org.junit.runners.Parameterized.Parameters; 108 109 import java.io.ByteArrayOutputStream; 110 import java.io.File; 111 import java.io.FileInputStream; 112 import java.io.FileOutputStream; 113 import java.io.IOException; 114 import java.io.InputStream; 115 import java.io.OutputStream; 116 import java.security.cert.CertificateEncodingException; 117 import java.text.DecimalFormat; 118 import java.util.ArrayList; 119 import java.util.Arrays; 120 import java.util.List; 121 import java.util.Optional; 122 import java.util.Random; 123 import java.util.concurrent.CompletableFuture; 124 import java.util.concurrent.TimeUnit; 125 import java.util.concurrent.TimeoutException; 126 import java.util.concurrent.atomic.AtomicInteger; 127 import java.util.concurrent.atomic.AtomicReference; 128 import java.util.function.BiConsumer; 129 import java.util.stream.Collectors; 130 131 @RunWith(Parameterized.class) 132 @AppModeFull 133 @AppModeNonSdkSandbox 134 public class PackageManagerShellCommandInstallTest { 135 static final String TEST_APP_PACKAGE = "com.example.helloworld"; 136 static final String TEST_VERIFIER_PACKAGE = "com.example.helloverifier"; 137 static final String TEST_SUFFICIENT_VERIFIER_PACKAGE = "com.example.hellosufficient"; 138 139 private static final String CTS_PACKAGE_NAME = "android.content.cts"; 140 141 private static final String TEST_APK_PATH = "/data/local/tmp/cts/content/"; 142 static final String TEST_HW5 = "HelloWorld5.apk"; 143 static final String TEST_HW_SYSTEM_USER_ONLY = "HelloWorldSystemUserOnly.apk"; 144 private static final String TEST_HW5_SPLIT0 = "HelloWorld5_hdpi-v4.apk"; 145 private static final String TEST_HW5_SPLIT1 = "HelloWorld5_mdpi-v4.apk"; 146 private static final String TEST_HW5_SPLIT2 = "HelloWorld5_xhdpi-v4.apk"; 147 private static final String TEST_HW5_SPLIT3 = "HelloWorld5_xxhdpi-v4.apk"; 148 private static final String TEST_HW5_SPLIT4 = "HelloWorld5_xxxhdpi-v4.apk"; 149 private static final String TEST_HW7 = "HelloWorld7.apk"; 150 private static final String TEST_HW7_SPLIT0 = "HelloWorld7_hdpi-v4.apk"; 151 private static final String TEST_HW7_SPLIT1 = "HelloWorld7_mdpi-v4.apk"; 152 private static final String TEST_HW7_SPLIT2 = "HelloWorld7_xhdpi-v4.apk"; 153 private static final String TEST_HW7_SPLIT3 = "HelloWorld7_xxhdpi-v4.apk"; 154 private static final String TEST_HW7_SPLIT4 = "HelloWorld7_xxxhdpi-v4.apk"; 155 156 private static final String TEST_SDK1_PACKAGE = "com.test.sdk1_1"; 157 private static final String TEST_SDK1_MAJOR_VERSION2_PACKAGE = "com.test.sdk1_2"; 158 private static final String TEST_SDK2_PACKAGE = "com.test.sdk2_2"; 159 private static final String TEST_SDK3_PACKAGE = "com.test.sdk3_3"; 160 private static final String TEST_SDK_USER_PACKAGE = "com.test.sdk.user"; 161 162 private static final String TEST_SDK1_NAME = "com.test.sdk1"; 163 private static final String TEST_SDK2_NAME = "com.test.sdk2"; 164 private static final String TEST_SDK3_NAME = "com.test.sdk3"; 165 166 private static final String TEST_SDK1 = "HelloWorldSdk1.apk"; 167 private static final String TEST_SDK1_UPDATED = "HelloWorldSdk1Updated.apk"; 168 private static final String TEST_SDK1_MAJOR_VERSION2 = "HelloWorldSdk1MajorVersion2.apk"; 169 private static final String TEST_SDK1_DIFFERENT_SIGNER = "HelloWorldSdk1DifferentSigner.apk"; 170 private static final String TEST_SDK2 = "HelloWorldSdk2.apk"; 171 private static final String TEST_SDK2_UPDATED = "HelloWorldSdk2Updated.apk"; 172 173 private static final String TEST_USING_SDK1_OPTIONAL = "HelloWorldUsingSdk1Optional.apk"; 174 175 private static final String TEST_USING_SDK1_OPTIONAL_SDK2 = 176 "HelloWorldUsingSdk1OptionalSdk2.apk"; 177 private static final String TEST_USING_SDK1 = "HelloWorldUsingSdk1.apk"; 178 private static final String TEST_USING_SDK1_AND_SDK2 = "HelloWorldUsingSdk1And2.apk"; 179 180 private static final String TEST_SDK3_USING_SDK1 = "HelloWorldSdk3UsingSdk1.apk"; 181 private static final String TEST_SDK3_USING_SDK1_AND_SDK2 = "HelloWorldSdk3UsingSdk1And2.apk"; 182 private static final String TEST_USING_SDK3 = "HelloWorldUsingSdk3.apk"; 183 184 185 private static final String TEST_SUFFICIENT = "HelloWorldWithSufficient.apk"; 186 187 private static final String TEST_SUFFICIENT_VERIFIER_REJECT = 188 "HelloSufficientVerifierReject.apk"; 189 190 private static final String TEST_VERIFIER_ALLOW = "HelloVerifierAllow.apk"; 191 private static final String TEST_VERIFIER_REJECT = "HelloVerifierReject.apk"; 192 private static final String TEST_VERIFIER_DELAYED_REJECT = "HelloVerifierDelayedReject.apk"; 193 private static final String TEST_VERIFIER_DISABLED = "HelloVerifierDisabled.apk"; 194 195 private static final String TEST_INSTALLER_APP = "HelloInstallerApp.apk"; 196 private static final String TEST_INSTALLER_APP_UPDATED = 197 "HelloInstallerAppUpdated.apk"; 198 199 private static final String TEST_INSTALLER_APP_ABSENT = "HelloInstallerAppAbsent.apk"; 200 private static final String TEST_INSTALLER_APP_ABSENT_UPDATED = 201 "HelloInstallerAppAbsentUpdated.apk"; 202 203 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 204 205 static final long DEFAULT_STREAMING_VERIFICATION_TIMEOUT_MS = 3 * 1000; 206 static final long VERIFICATION_BROADCAST_RECEIVED_TIMEOUT_MS = 10 * 1000; 207 208 @Rule 209 public AbandonAllPackageSessionsRule mAbandonSessionsRule = new AbandonAllPackageSessionsRule(); 210 211 @Rule 212 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 213 214 @Parameter 215 public int mDataLoaderType; 216 217 @Parameters initParameters()218 public static Iterable<Object> initParameters() { 219 return Arrays.asList(DATA_LOADER_TYPE_NONE, DATA_LOADER_TYPE_STREAMING, 220 DATA_LOADER_TYPE_INCREMENTAL); 221 } 222 223 private boolean mStreaming = false; 224 private boolean mIncremental = false; 225 private boolean mVerifierTimeoutTest = false; 226 private String mInstall = ""; 227 private static long sStreamingVerificationTimeoutMs = DEFAULT_STREAMING_VERIFICATION_TIMEOUT_MS; 228 getPackageInstaller()229 private static PackageInstaller getPackageInstaller() { 230 return getPackageManager().getPackageInstaller(); 231 } 232 getPackageManager()233 private static PackageManager getPackageManager() { 234 return InstrumentationRegistry.getContext().getPackageManager(); 235 } 236 getContext()237 private static Context getContext() { 238 return InstrumentationRegistry.getContext(); 239 } 240 getUiAutomation()241 private static UiAutomation getUiAutomation() { 242 return InstrumentationRegistry.getInstrumentation().getUiAutomation(); 243 } 244 executeShellCommand(String command)245 /* package */ static String executeShellCommand(String command) throws IOException { 246 final ParcelFileDescriptor stdout = getUiAutomation().executeShellCommand(command); 247 try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) { 248 return readFullStream(inputStream); 249 } 250 } 251 executeShellCommand(String command, File input)252 private static String executeShellCommand(String command, File input) 253 throws IOException { 254 return executeShellCommand(command, new File[]{input}); 255 } 256 executeShellCommand(String command, File[] inputs)257 private static String executeShellCommand(String command, File[] inputs) 258 throws IOException { 259 final ParcelFileDescriptor[] pfds = getUiAutomation().executeShellCommandRw(command); 260 ParcelFileDescriptor stdout = pfds[0]; 261 ParcelFileDescriptor stdin = pfds[1]; 262 try (FileOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream( 263 stdin)) { 264 for (File input : inputs) { 265 try (FileInputStream inputStream = new FileInputStream(input)) { 266 writeFullStream(inputStream, outputStream, input.length()); 267 } 268 } 269 } 270 try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) { 271 return readFullStream(inputStream); 272 } 273 } 274 readFullStream(InputStream inputStream)275 private static String readFullStream(InputStream inputStream) throws IOException { 276 ByteArrayOutputStream result = new ByteArrayOutputStream(); 277 writeFullStream(inputStream, result, -1); 278 return result.toString("UTF-8"); 279 } 280 writeFullStream(InputStream inputStream, OutputStream outputStream, long expected)281 private static void writeFullStream(InputStream inputStream, OutputStream outputStream, 282 long expected) 283 throws IOException { 284 byte[] buffer = new byte[1024]; 285 long total = 0; 286 int length; 287 while ((length = inputStream.read(buffer)) != -1) { 288 outputStream.write(buffer, 0, length); 289 total += length; 290 } 291 if (expected > 0) { 292 assertEquals(expected, total); 293 } 294 } 295 writeFileToSession(PackageInstaller.Session session, String name, String apk)296 private static void writeFileToSession(PackageInstaller.Session session, String name, 297 String apk) throws IOException { 298 File file = new File(createApkPath(apk)); 299 try (OutputStream os = session.openWrite(name, 0, file.length()); 300 InputStream is = new FileInputStream(file)) { 301 writeFullStream(is, os, file.length()); 302 } 303 } 304 305 @BeforeClass onBeforeClass()306 public static void onBeforeClass() throws Exception { 307 try { 308 sStreamingVerificationTimeoutMs = Long.parseUnsignedLong( 309 executeShellCommand("settings get global streaming_verifier_timeout")); 310 } catch (NumberFormatException ignore) { 311 } 312 } 313 314 @Before onBefore()315 public void onBefore() throws Exception { 316 // Check if Incremental is allowed and skip incremental tests otherwise. 317 assumeFalse(mDataLoaderType == DATA_LOADER_TYPE_INCREMENTAL 318 && !checkIncrementalDeliveryFeature()); 319 320 mStreaming = mDataLoaderType != DATA_LOADER_TYPE_NONE; 321 mIncremental = mDataLoaderType == DATA_LOADER_TYPE_INCREMENTAL; 322 // Don't repeat verifier timeout tests for non-Incremental installs. 323 mVerifierTimeoutTest = !mStreaming || mIncremental; 324 325 mInstall = mDataLoaderType == DATA_LOADER_TYPE_NONE ? " install " : 326 mDataLoaderType == DATA_LOADER_TYPE_STREAMING ? " install-streaming " : 327 " install-incremental "; 328 329 uninstallPackageSilently(TEST_APP_PACKAGE); 330 331 executeShellCommand("settings put global verifier_verify_adb_installs 0"); 332 } 333 onBeforeSdkTests()334 private void onBeforeSdkTests() throws Exception { 335 assumeFalse(mStreaming); 336 337 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 338 uninstallPackageSilently(TEST_SDK3_PACKAGE); 339 uninstallPackageSilently(TEST_SDK2_PACKAGE); 340 uninstallPackageSilently(TEST_SDK1_PACKAGE); 341 uninstallPackageSilently(TEST_SDK1_MAJOR_VERSION2_PACKAGE); 342 343 setSystemProperty("debug.pm.uses_sdk_library_default_cert_digest", "invalid"); 344 setSystemProperty("debug.pm.prune_unused_shared_libraries_delay", "invalid"); 345 } 346 347 @AfterClass onAfterClass()348 public static void onAfterClass() throws Exception { 349 uninstallPackageSilently(TEST_APP_PACKAGE); 350 351 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 352 uninstallPackageSilently(TEST_SUFFICIENT_VERIFIER_PACKAGE); 353 354 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 355 uninstallPackageSilently(TEST_SDK3_PACKAGE); 356 uninstallPackageSilently(TEST_SDK2_PACKAGE); 357 uninstallPackageSilently(TEST_SDK1_PACKAGE); 358 uninstallPackageSilently(TEST_SDK1_MAJOR_VERSION2_PACKAGE); 359 360 // Set the test override to invalid. 361 setSystemProperty("debug.pm.uses_sdk_library_default_cert_digest", "invalid"); 362 setSystemProperty("debug.pm.prune_unused_shared_libraries_delay", "invalid"); 363 setSystemProperty("debug.pm.adb_verifier_override_packages", "invalid"); 364 } 365 checkIncrementalDeliveryFeature()366 private boolean checkIncrementalDeliveryFeature() { 367 final Context context = InstrumentationRegistry.getInstrumentation().getContext(); 368 return context.getPackageManager().hasSystemFeature( 369 PackageManager.FEATURE_INCREMENTAL_DELIVERY); 370 } 371 372 @Test testAppInstall()373 public void testAppInstall() throws Exception { 374 installPackage(TEST_HW5); 375 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 376 } 377 378 @Test testAppInstallInvalidUser()379 public void testAppInstallInvalidUser() throws Exception { 380 File file = new File(createApkPath(TEST_HW5)); 381 // MAX_USER_ID = UserHandle.MAX_SECONDARY_USER_ID 382 // ideally the test environment will not reach 999 383 String result = executeShellCommand( 384 "pm " + mInstall + " --user 999" + " -t -g " + file.getPath()); 385 assertThat(result).isEqualTo("Failure [user 999 doesn't exist]\n"); 386 } 387 388 @Test testAppUnInstallInvalidUser()389 public void testAppUnInstallInvalidUser() throws Exception { 390 // MAX_USER_ID = UserHandle.MAX_SECONDARY_USER_ID 391 // ideally the test environment will not reach 999 392 String result = executeShellCommand("pm uninstall --user 999 " + TEST_APP_PACKAGE); 393 assertThat(result).isEqualTo("Failure [user 999 doesn't exist]\n"); 394 } 395 396 @Test testAppInstallErr()397 public void testAppInstallErr() throws Exception { 398 assumeTrue(mStreaming); 399 File file = new File(createApkPath(TEST_HW5)); 400 String command = "pm " + mInstall + " -t -g " + file.getPath() + (new Random()).nextLong(); 401 String commandResult = executeShellCommand(command); 402 assertEquals("Failure [failed to add file(s)]\n", commandResult); 403 assertFalse(isAppInstalled(TEST_APP_PACKAGE)); 404 } 405 406 @Test testAppInstallStdIn()407 public void testAppInstallStdIn() throws Exception { 408 installPackageStdIn(TEST_HW5); 409 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 410 } 411 412 @Test testAppInstallStdInErr()413 public void testAppInstallStdInErr() throws Exception { 414 File file = new File(createApkPath(TEST_HW5)); 415 String commandResult = executeShellCommand("pm " + mInstall + " -t -g -S " + file.length(), 416 new File[]{}); 417 if (mIncremental) { 418 assertTrue(commandResult, commandResult.startsWith("Failure [")); 419 } else { 420 assertTrue(commandResult, 421 commandResult.startsWith("Failure [INSTALL_PARSE_FAILED_NOT_APK")); 422 } 423 assertFalse(isAppInstalled(TEST_APP_PACKAGE)); 424 } 425 426 @Test 427 @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_GET_PACKAGE_STORAGE_STATS) testGetPackageStorageStats()428 public void testGetPackageStorageStats() throws Exception { 429 installPackage(TEST_HW5); 430 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 431 432 StorageStatsManager storageStatsManager = 433 getContext().getSystemService(StorageStatsManager.class); 434 StorageStats stats = 435 storageStatsManager.queryStatsForPackage(StorageManager.UUID_DEFAULT, 436 TEST_APP_PACKAGE, android.os.Process.myUserHandle()); 437 438 String commandResult = 439 executeShellCommand("pm get-package-storage-stats " + TEST_APP_PACKAGE); 440 String[] lines = commandResult.split("\n"); 441 for (String line : lines) { 442 String dataType = line.split(": ")[0]; 443 String value = line.split(": ")[1]; 444 switch (dataType) { 445 case "code": 446 assertEquals(value, getDataSizeDisplay(stats.getAppBytes())); 447 break; 448 case "data": 449 assertEquals(value, getDataSizeDisplay(stats.getDataBytes())); 450 break; 451 case "cache": 452 assertEquals(value, getDataSizeDisplay(stats.getCacheBytes())); 453 break; 454 case "apk": 455 assertEquals(value, getDataSizeDisplay(stats.getAppBytesByDataType( 456 StorageStats.APP_DATA_TYPE_FILE_TYPE_APK))); 457 break; 458 case "lib": 459 assertEquals(value, getDataSizeDisplay(stats.getAppBytesByDataType( 460 StorageStats.APP_DATA_TYPE_LIB))); 461 break; 462 case "dm": 463 assertEquals(value, getDataSizeDisplay(stats.getAppBytesByDataType( 464 StorageStats.APP_DATA_TYPE_FILE_TYPE_DM))); 465 break; 466 case "dexopt artifacts": 467 assertEquals(value, getDataSizeDisplay(stats.getAppBytesByDataType( 468 StorageStats.APP_DATA_TYPE_FILE_TYPE_DEXOPT_ARTIFACT))); 469 break; 470 case "current profile": 471 assertEquals(value, getDataSizeDisplay(stats.getAppBytesByDataType( 472 StorageStats.APP_DATA_TYPE_FILE_TYPE_CURRENT_PROFILE))); 473 break; 474 case "reference profile": 475 assertEquals(value, getDataSizeDisplay(stats.getAppBytesByDataType( 476 StorageStats.APP_DATA_TYPE_FILE_TYPE_REFERENCE_PROFILE))); 477 break; 478 case "external cache": 479 assertEquals(value, getDataSizeDisplay(stats.getExternalCacheBytes())); 480 break; 481 } 482 } 483 } 484 485 @Test testAppUpdate()486 public void testAppUpdate() throws Exception { 487 installPackage(TEST_HW5); 488 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 489 updatePackage(TEST_APP_PACKAGE, TEST_HW7); 490 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 491 } 492 493 @Test testAppUpdateSameApk()494 public void testAppUpdateSameApk() throws Exception { 495 installPackage(TEST_HW5); 496 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 497 updatePackage(TEST_APP_PACKAGE, TEST_HW5); 498 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 499 } 500 501 @Test testAppUpdateStdIn()502 public void testAppUpdateStdIn() throws Exception { 503 installPackageStdIn(TEST_HW5); 504 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 505 updatePackageStdIn(TEST_APP_PACKAGE, TEST_HW7); 506 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 507 } 508 509 @Test testAppUpdateStdInSameApk()510 public void testAppUpdateStdInSameApk() throws Exception { 511 installPackageStdIn(TEST_HW5); 512 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 513 updatePackageStdIn(TEST_APP_PACKAGE, TEST_HW5); 514 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 515 } 516 517 @Test testAppUpdateSkipEnable()518 public void testAppUpdateSkipEnable() throws Exception { 519 assumeFalse(mStreaming); 520 installPackage(TEST_HW5); 521 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 522 assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 523 getPackageManager().getApplicationEnabledSetting(TEST_APP_PACKAGE)); 524 disablePackage(TEST_APP_PACKAGE); 525 assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 526 getPackageManager().getApplicationEnabledSetting(TEST_APP_PACKAGE)); 527 updatePackage(TEST_APP_PACKAGE, TEST_HW5); 528 assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 529 getPackageManager().getApplicationEnabledSetting(TEST_APP_PACKAGE)); 530 disablePackage(TEST_APP_PACKAGE); 531 assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 532 getPackageManager().getApplicationEnabledSetting(TEST_APP_PACKAGE)); 533 updatePackageSkipEnable(TEST_APP_PACKAGE, TEST_HW5); 534 assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 535 getPackageManager().getApplicationEnabledSetting(TEST_APP_PACKAGE)); 536 } 537 538 @Test testSplitsInstall()539 public void testSplitsInstall() throws Exception { 540 assumeFalse(mStreaming); // Tested in testSplitsBatchInstall. 541 installSplits(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 542 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 543 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 544 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 545 getSplits(TEST_APP_PACKAGE)); 546 } 547 548 @Test testSplitsInstallStdIn()549 public void testSplitsInstallStdIn() throws Exception { 550 installSplitsStdIn(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 551 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}, ""); 552 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 553 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 554 getSplits(TEST_APP_PACKAGE)); 555 } 556 557 @Test testSplitsInstallDash()558 public void testSplitsInstallDash() throws Exception { 559 installSplitsStdIn(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 560 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}, "-"); 561 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 562 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 563 getSplits(TEST_APP_PACKAGE)); 564 } 565 566 @Test testSplitsBatchInstall()567 public void testSplitsBatchInstall() throws Exception { 568 installSplitsBatch(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 569 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 570 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 571 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 572 getSplits(TEST_APP_PACKAGE)); 573 } 574 575 @Test testSplitsUpdate()576 public void testSplitsUpdate() throws Exception { 577 assumeFalse(mStreaming); // Tested in testSplitsBatchUpdate. 578 installSplits(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 579 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 580 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 581 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 582 getSplits(TEST_APP_PACKAGE)); 583 updateSplits(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1, TEST_HW7_SPLIT2, 584 TEST_HW7_SPLIT3, TEST_HW7_SPLIT4}); 585 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 586 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 587 getSplits(TEST_APP_PACKAGE)); 588 } 589 590 591 @Test testSplitsAdd()592 public void testSplitsAdd() throws Exception { 593 assumeFalse(mStreaming); // Tested in testSplitsBatchAdd. 594 installSplits(new String[]{TEST_HW5}); 595 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 596 assertEquals("base", getSplits(TEST_APP_PACKAGE)); 597 598 updateSplits(new String[]{TEST_HW5_SPLIT0}); 599 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 600 assertEquals("base, config.hdpi", getSplits(TEST_APP_PACKAGE)); 601 602 updateSplits(new String[]{TEST_HW5_SPLIT1}); 603 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 604 assertEquals("base, config.hdpi, config.mdpi", getSplits(TEST_APP_PACKAGE)); 605 606 updateSplits(new String[]{TEST_HW5_SPLIT2}); 607 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 608 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi", 609 getSplits(TEST_APP_PACKAGE)); 610 611 updateSplits(new String[]{TEST_HW5_SPLIT3}); 612 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 613 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi", 614 getSplits(TEST_APP_PACKAGE)); 615 616 updateSplits(new String[]{TEST_HW5_SPLIT4}); 617 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 618 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 619 getSplits(TEST_APP_PACKAGE)); 620 } 621 622 @Test testSplitsUpdateStdIn()623 public void testSplitsUpdateStdIn() throws Exception { 624 installSplitsStdIn(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 625 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}, ""); 626 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 627 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 628 getSplits(TEST_APP_PACKAGE)); 629 installSplitsStdIn(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1, TEST_HW7_SPLIT2, 630 TEST_HW7_SPLIT3, TEST_HW7_SPLIT4}, ""); 631 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 632 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 633 getSplits(TEST_APP_PACKAGE)); 634 } 635 636 @Test testSplitsUpdateDash()637 public void testSplitsUpdateDash() throws Exception { 638 installSplitsStdIn(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 639 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}, "-"); 640 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 641 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 642 getSplits(TEST_APP_PACKAGE)); 643 installSplitsStdIn(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1, TEST_HW7_SPLIT2, 644 TEST_HW7_SPLIT3, TEST_HW7_SPLIT4}, "-"); 645 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 646 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 647 getSplits(TEST_APP_PACKAGE)); 648 } 649 650 @Test testSplitsBatchUpdate()651 public void testSplitsBatchUpdate() throws Exception { 652 installSplitsBatch(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 653 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 654 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 655 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 656 getSplits(TEST_APP_PACKAGE)); 657 updateSplitsBatch( 658 new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1, TEST_HW7_SPLIT2, 659 TEST_HW7_SPLIT3, TEST_HW7_SPLIT4}); 660 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 661 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 662 getSplits(TEST_APP_PACKAGE)); 663 } 664 665 @Test testSplitsBatchAdd()666 public void testSplitsBatchAdd() throws Exception { 667 installSplitsBatch(new String[]{TEST_HW5}); 668 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 669 assertEquals("base", getSplits(TEST_APP_PACKAGE)); 670 671 updateSplitsBatch(new String[]{TEST_HW5_SPLIT0, TEST_HW5_SPLIT1}); 672 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 673 assertEquals("base, config.hdpi, config.mdpi", getSplits(TEST_APP_PACKAGE)); 674 675 updateSplitsBatch(new String[]{TEST_HW5_SPLIT2, TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 676 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 677 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 678 getSplits(TEST_APP_PACKAGE)); 679 } 680 681 @Test testSplitsUninstall()682 public void testSplitsUninstall() throws Exception { 683 assumeFalse(mStreaming); // Tested in testSplitsBatchUninstall. 684 installSplits(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 685 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 686 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 687 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 688 getSplits(TEST_APP_PACKAGE)); 689 uninstallSplits(TEST_APP_PACKAGE, new String[]{"config.hdpi"}); 690 assertEquals("base, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 691 getSplits(TEST_APP_PACKAGE)); 692 uninstallSplits(TEST_APP_PACKAGE, new String[]{"config.xxxhdpi", "config.xhdpi"}); 693 assertEquals("base, config.mdpi, config.xxhdpi", getSplits(TEST_APP_PACKAGE)); 694 } 695 696 @Test testSplitsBatchUninstall()697 public void testSplitsBatchUninstall() throws Exception { 698 installSplitsBatch(new String[]{TEST_HW5, TEST_HW5_SPLIT0, TEST_HW5_SPLIT1, TEST_HW5_SPLIT2, 699 TEST_HW5_SPLIT3, TEST_HW5_SPLIT4}); 700 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 701 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 702 getSplits(TEST_APP_PACKAGE)); 703 uninstallSplitsBatch(TEST_APP_PACKAGE, new String[]{"config.hdpi"}); 704 assertEquals("base, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 705 getSplits(TEST_APP_PACKAGE)); 706 uninstallSplitsBatch(TEST_APP_PACKAGE, new String[]{"config.xxxhdpi", "config.xhdpi"}); 707 assertEquals("base, config.mdpi, config.xxhdpi", getSplits(TEST_APP_PACKAGE)); 708 } 709 710 @Test testSplitsRemove()711 public void testSplitsRemove() throws Exception { 712 assumeFalse(mStreaming); // Tested in testSplitsBatchRemove. 713 installSplits(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1, TEST_HW7_SPLIT2, 714 TEST_HW7_SPLIT3, TEST_HW7_SPLIT4}); 715 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 716 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 717 getSplits(TEST_APP_PACKAGE)); 718 719 String sessionId = createUpdateSession(TEST_APP_PACKAGE); 720 removeSplits(sessionId, new String[]{"config.hdpi"}); 721 commitSession(sessionId); 722 assertEquals("base, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 723 getSplits(TEST_APP_PACKAGE)); 724 725 sessionId = createUpdateSession(TEST_APP_PACKAGE); 726 removeSplits(sessionId, new String[]{"config.xxxhdpi", "config.xhdpi"}); 727 commitSession(sessionId); 728 assertEquals("base, config.mdpi, config.xxhdpi", getSplits(TEST_APP_PACKAGE)); 729 } 730 731 @Test testSplitsBatchRemove()732 public void testSplitsBatchRemove() throws Exception { 733 installSplitsBatch(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1, TEST_HW7_SPLIT2, 734 TEST_HW7_SPLIT3, TEST_HW7_SPLIT4}); 735 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 736 assertEquals("base, config.hdpi, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 737 getSplits(TEST_APP_PACKAGE)); 738 739 String sessionId = createUpdateSession(TEST_APP_PACKAGE); 740 removeSplitsBatch(sessionId, new String[]{"config.hdpi"}); 741 commitSession(sessionId); 742 assertEquals("base, config.mdpi, config.xhdpi, config.xxhdpi, config.xxxhdpi", 743 getSplits(TEST_APP_PACKAGE)); 744 745 sessionId = createUpdateSession(TEST_APP_PACKAGE); 746 removeSplitsBatch(sessionId, new String[]{"config.xxxhdpi", "config.xhdpi"}); 747 commitSession(sessionId); 748 assertEquals("base, config.mdpi, config.xxhdpi", getSplits(TEST_APP_PACKAGE)); 749 } 750 751 @Test testAppInstallErrDuplicate()752 public void testAppInstallErrDuplicate() throws Exception { 753 assumeTrue(mStreaming); 754 String split = createApkPath(TEST_HW5); 755 String commandResult = executeShellCommand( 756 "pm " + mInstall + " -t -g " + split + " " + split); 757 assertEquals("Failure [failed to add file(s)]\n", commandResult); 758 assertFalse(isAppInstalled(TEST_APP_PACKAGE)); 759 } 760 761 @Test testDontKillWithSplit()762 public void testDontKillWithSplit() throws Exception { 763 assumeFalse(mStreaming); 764 installPackage(TEST_HW5); 765 installDontKillSplit(); 766 } 767 installDontKillSplit()768 private void installDontKillSplit() throws Exception { 769 getUiAutomation().adoptShellPermissionIdentity(); 770 try { 771 final PackageInstaller installer = getPackageInstaller(); 772 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 773 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 774 params.setAppPackageName(TEST_APP_PACKAGE); 775 params.setDontKillApp(true); 776 777 final int sessionId = installer.createSession(params); 778 PackageInstaller.Session session = installer.openSession(sessionId); 779 assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0); 780 781 writeFileToSession(session, "hw5_split0", TEST_HW5_SPLIT0); 782 783 final CompletableFuture<Boolean> result = new CompletableFuture<>(); 784 final CompletableFuture<Integer> status = new CompletableFuture<>(); 785 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 786 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 787 @Override 788 public void send(int code, Intent intent, String resolvedType, 789 IBinder whitelistToken, IIntentReceiver finishedReceiver, 790 String requiredPermission, Bundle options) throws RemoteException { 791 boolean dontKillApp = 792 (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0; 793 status.complete( 794 intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MIN_VALUE)); 795 statusMessage.complete( 796 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 797 result.complete(dontKillApp); 798 } 799 })); 800 801 // We are adding split. OK to have the flag. 802 assertTrue(result.get()); 803 // Verify that the return status is set 804 assertEquals(statusMessage.get(), PackageInstaller.STATUS_SUCCESS, (int) status.get()); 805 } finally { 806 getUiAutomation().dropShellPermissionIdentity(); 807 } 808 } 809 810 @RequiresFlagsEnabled(Flags.FLAG_IMPROVE_INSTALL_DONT_KILL) 811 @Test testDontKillOldPathsArePreserved()812 public void testDontKillOldPathsArePreserved() throws Exception { 813 assumeFalse(mStreaming); 814 installPackage(TEST_HW5); 815 String oldPath = 816 getPackageManager().getApplicationInfo(TEST_APP_PACKAGE, 0).publicSourceDir; 817 installDontKillSplit(); 818 819 List<String> oldPaths = getOldCodePaths(TEST_APP_PACKAGE); 820 assertNotNull(oldPaths); 821 assertEquals(1, oldPaths.size()); 822 // publicSourceDir contains the full path to the APK 823 // oldPaths only contains paths to directory 824 assertTrue(oldPath.startsWith(oldPaths.get(0))); 825 } 826 827 @Test testDontKillRemovedWithBaseApkFullInstall()828 public void testDontKillRemovedWithBaseApkFullInstall() throws Exception { 829 assumeFalse(mStreaming); 830 installPackage(TEST_HW5); 831 832 getUiAutomation().adoptShellPermissionIdentity(); 833 try { 834 final PackageInstaller installer = getPackageInstaller(); 835 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 836 params.setAppPackageName(TEST_APP_PACKAGE); 837 params.setDontKillApp(true); 838 839 final int sessionId = installer.createSession(params); 840 PackageInstaller.Session session = installer.openSession(sessionId); 841 assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0); 842 843 writeFileToSession(session, "hw7", TEST_HW7); 844 845 final CompletableFuture<Boolean> result = new CompletableFuture<>(); 846 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 847 @Override 848 public void send(int code, Intent intent, String resolvedType, 849 IBinder whitelistToken, IIntentReceiver finishedReceiver, 850 String requiredPermission, Bundle options) throws RemoteException { 851 boolean dontKillApp = 852 (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0; 853 result.complete(dontKillApp); 854 } 855 })); 856 857 // We are updating base.apk. Flag to be removed. 858 assertFalse(result.get()); 859 } finally { 860 getUiAutomation().dropShellPermissionIdentity(); 861 } 862 } 863 864 @Test testDontKillRemovedWithBaseApk()865 public void testDontKillRemovedWithBaseApk() throws Exception { 866 assumeFalse(mStreaming); 867 installPackage(TEST_HW5); 868 869 getUiAutomation().adoptShellPermissionIdentity(); 870 try { 871 final PackageInstaller installer = getPackageInstaller(); 872 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 873 params.setAppPackageName(TEST_APP_PACKAGE); 874 params.setDontKillApp(true); 875 876 final int sessionId = installer.createSession(params); 877 PackageInstaller.Session session = installer.openSession(sessionId); 878 assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0); 879 880 writeFileToSession(session, "hw7", TEST_HW7); 881 882 final CompletableFuture<Boolean> result = new CompletableFuture<>(); 883 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 884 @Override 885 public void send(int code, Intent intent, String resolvedType, 886 IBinder whitelistToken, IIntentReceiver finishedReceiver, 887 String requiredPermission, Bundle options) throws RemoteException { 888 boolean dontKillApp = 889 (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0; 890 result.complete(dontKillApp); 891 } 892 })); 893 894 // We are updating base.apk. Flag to be removed. 895 assertFalse(result.get()); 896 } finally { 897 getUiAutomation().dropShellPermissionIdentity(); 898 } 899 } 900 901 @Test testDontKillRemovedWithRemovedSplit()902 public void testDontKillRemovedWithRemovedSplit() throws Exception { 903 assumeFalse(mStreaming); 904 installSplitsBatch(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1}); 905 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 906 assertEquals("base, config.hdpi, config.mdpi", getSplits(TEST_APP_PACKAGE)); 907 908 getUiAutomation().adoptShellPermissionIdentity(); 909 try { 910 final PackageInstaller installer = getPackageInstaller(); 911 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 912 params.setAppPackageName(TEST_APP_PACKAGE); 913 params.setDontKillApp(true); 914 915 final int sessionId = installer.createSession(params); 916 PackageInstaller.Session session = installer.openSession(sessionId); 917 assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0); 918 session.removeSplit("config.mdpi"); 919 920 final CompletableFuture<Boolean> result = new CompletableFuture<>(); 921 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 922 @Override 923 public void send(int code, Intent intent, String resolvedType, 924 IBinder whitelistToken, IIntentReceiver finishedReceiver, 925 String requiredPermission, Bundle options) throws RemoteException { 926 boolean dontKillApp = 927 (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0; 928 result.complete(dontKillApp); 929 } 930 })); 931 932 // We are removing a split apk. Flag should be removed. 933 assertFalse(result.get()); 934 } finally { 935 getUiAutomation().dropShellPermissionIdentity(); 936 } 937 } 938 939 @Test testDontKillRemovedWithReplacedSplit()940 public void testDontKillRemovedWithReplacedSplit() throws Exception { 941 assumeFalse(mStreaming); 942 installSplitsBatch(new String[]{TEST_HW7, TEST_HW7_SPLIT0, TEST_HW7_SPLIT1}); 943 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 944 assertEquals("base, config.hdpi, config.mdpi", getSplits(TEST_APP_PACKAGE)); 945 946 getUiAutomation().adoptShellPermissionIdentity(); 947 try { 948 final PackageInstaller installer = getPackageInstaller(); 949 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 950 params.setAppPackageName(TEST_APP_PACKAGE); 951 params.setDontKillApp(true); 952 953 final int sessionId = installer.createSession(params); 954 PackageInstaller.Session session = installer.openSession(sessionId); 955 assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0); 956 957 writeFileToSession(session, "split_config.mdpi", TEST_HW7_SPLIT1); 958 959 final CompletableFuture<Boolean> result = new CompletableFuture<>(); 960 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 961 @Override 962 public void send(int code, Intent intent, String resolvedType, 963 IBinder whitelistToken, IIntentReceiver finishedReceiver, 964 String requiredPermission, Bundle options) throws RemoteException { 965 boolean dontKillApp = 966 (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0; 967 result.complete(dontKillApp); 968 } 969 })); 970 971 // We are replacing an existing split apk. Flag should be removed. 972 assertFalse(result.get()); 973 } finally { 974 getUiAutomation().dropShellPermissionIdentity(); 975 } 976 } 977 978 @Test testDataLoaderParamsApiV1()979 public void testDataLoaderParamsApiV1() throws Exception { 980 assumeTrue(mStreaming); 981 982 getUiAutomation().adoptShellPermissionIdentity(); 983 try { 984 final PackageInstaller installer = getPackageInstaller(); 985 986 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 987 988 final int sessionId = installer.createSession(params); 989 PackageInstaller.Session session = installer.openSession(sessionId); 990 991 assertEquals(null, session.getDataLoaderParams()); 992 993 installer.abandonSession(sessionId); 994 } finally { 995 getUiAutomation().dropShellPermissionIdentity(); 996 } 997 } 998 999 @Test testDataLoaderParamsApiV2()1000 public void testDataLoaderParamsApiV2() throws Exception { 1001 assumeTrue(mStreaming); 1002 1003 getUiAutomation().adoptShellPermissionIdentity(); 1004 try { 1005 final PackageInstaller installer = getPackageInstaller(); 1006 1007 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1008 final ComponentName componentName = new ComponentName("foo", "bar"); 1009 final String args = "args"; 1010 params.setDataLoaderParams( 1011 mIncremental ? DataLoaderParams.forIncremental(componentName, args) 1012 : DataLoaderParams.forStreaming(componentName, args)); 1013 1014 final int sessionId = installer.createSession(params); 1015 PackageInstaller.Session session = installer.openSession(sessionId); 1016 1017 DataLoaderParams dataLoaderParams = session.getDataLoaderParams(); 1018 assertEquals(mIncremental ? DATA_LOADER_TYPE_INCREMENTAL : DATA_LOADER_TYPE_STREAMING, 1019 dataLoaderParams.getType()); 1020 assertEquals("foo", dataLoaderParams.getComponentName().getPackageName()); 1021 assertEquals("bar", dataLoaderParams.getComponentName().getClassName()); 1022 assertEquals("args", dataLoaderParams.getArguments()); 1023 1024 installer.abandonSession(sessionId); 1025 } finally { 1026 getUiAutomation().dropShellPermissionIdentity(); 1027 } 1028 } 1029 1030 @Test testRemoveFileApiV2()1031 public void testRemoveFileApiV2() throws Exception { 1032 assumeTrue(mStreaming); 1033 1034 getUiAutomation().adoptShellPermissionIdentity(); 1035 try { 1036 final PackageInstaller installer = getPackageInstaller(); 1037 1038 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 1039 params.setAppPackageName("com.package.name"); 1040 final ComponentName componentName = new ComponentName("foo", "bar"); 1041 final String args = "args"; 1042 params.setDataLoaderParams( 1043 mIncremental ? DataLoaderParams.forIncremental(componentName, args) 1044 : DataLoaderParams.forStreaming(componentName, args)); 1045 1046 final int sessionId = installer.createSession(params); 1047 PackageInstaller.Session session = installer.openSession(sessionId); 1048 1049 session.addFile(LOCATION_DATA_APP, "base.apk", 123, "123".getBytes(), null); 1050 String[] files = session.getNames(); 1051 assertEquals(1, files.length); 1052 assertEquals("base.apk", files[0]); 1053 1054 session.removeFile(LOCATION_DATA_APP, "base.apk"); 1055 files = session.getNames(); 1056 assertEquals(2, files.length); 1057 assertEquals("base.apk", files[0]); 1058 assertEquals("base.apk.removed", files[1]); 1059 1060 installer.abandonSession(sessionId); 1061 } finally { 1062 getUiAutomation().dropShellPermissionIdentity(); 1063 } 1064 } 1065 1066 @Test 1067 @RequiresFlagsDisabled(Flags.FLAG_DISALLOW_SDK_LIBS_TO_BE_APPS) testSdkInstallAndUpdate_sdkLibsBeAppsHasAppId()1068 public void testSdkInstallAndUpdate_sdkLibsBeAppsHasAppId() throws Exception { 1069 onBeforeSdkTests(); 1070 1071 installPackage(TEST_SDK1); 1072 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1073 1074 SystemUtil.runWithShellPermissionIdentity(() -> { 1075 // No uid is assigned for SDK package 1076 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK1_PACKAGE, 1077 PackageManager.ApplicationInfoFlags.of( 1078 MATCH_STATIC_SHARED_AND_SDK_LIBRARIES)); 1079 assertThat(appInfo.uid).isGreaterThan(Process.INVALID_UID); 1080 }); 1081 1082 // Same APK. 1083 installPackage(TEST_SDK1); 1084 1085 // Updated APK. 1086 installPackage(TEST_SDK1_UPDATED); 1087 1088 // Reverted APK. 1089 installPackage(TEST_SDK1); 1090 1091 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1092 } 1093 1094 @Test 1095 @RequiresFlagsEnabled(Flags.FLAG_DISALLOW_SDK_LIBS_TO_BE_APPS) testSdkInstallAndUpdate_blockSdkLibsBeAppsNoAppId()1096 public void testSdkInstallAndUpdate_blockSdkLibsBeAppsNoAppId() throws Exception { 1097 onBeforeSdkTests(); 1098 1099 installPackage(TEST_SDK1); 1100 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1101 1102 SystemUtil.runWithShellPermissionIdentity(() -> { 1103 // No uid is assigned for SDK package 1104 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK1_PACKAGE, 1105 PackageManager.ApplicationInfoFlags.of( 1106 MATCH_STATIC_SHARED_AND_SDK_LIBRARIES)); 1107 assertThat(appInfo.uid).isEqualTo(Process.INVALID_UID); 1108 }); 1109 1110 // Same APK. 1111 installPackage(TEST_SDK1); 1112 1113 // Updated APK. 1114 installPackage(TEST_SDK1_UPDATED); 1115 1116 // Reverted APK. 1117 installPackage(TEST_SDK1); 1118 1119 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1120 } 1121 1122 @Test testGetPackageInfoForSdk_notSystemOrShell()1123 public void testGetPackageInfoForSdk_notSystemOrShell() throws Exception { 1124 onBeforeSdkTests(); 1125 1126 installPackage(TEST_SDK1); 1127 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1128 1129 // Normal access 1130 assertThrows(PackageManager.NameNotFoundException.class, 1131 () -> getPackageManager().getPackageInfo(TEST_SDK1_PACKAGE, 1132 PackageManager.PackageInfoFlags.of(MATCH_STATIC_SHARED_AND_SDK_LIBRARIES))); 1133 } 1134 1135 @Test testGetApplicationInfoForSdk_notSystemOrShell()1136 public void testGetApplicationInfoForSdk_notSystemOrShell() throws Exception { 1137 onBeforeSdkTests(); 1138 1139 installPackage(TEST_SDK1); 1140 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1141 1142 // Normal access 1143 assertThrows(PackageManager.NameNotFoundException.class, 1144 () -> getPackageManager().getApplicationInfo(TEST_SDK1_PACKAGE, 1145 PackageManager.ApplicationInfoFlags.of( 1146 MATCH_STATIC_SHARED_AND_SDK_LIBRARIES))); 1147 } 1148 1149 @Test testSharedLibraryAccess_notSystemOrShell()1150 public void testSharedLibraryAccess_notSystemOrShell() throws Exception { 1151 onBeforeSdkTests(); 1152 1153 installPackage(TEST_SDK1); 1154 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1155 1156 // Normal access 1157 List<SharedLibraryInfo> shareLibs = getPackageManager().getSharedLibraries(/*flags=*/ 0); 1158 SharedLibraryInfo sdk = findLibrary(shareLibs, TEST_SDK1_NAME, 1); 1159 assertThat(sdk).isNull(); 1160 } 1161 1162 @Test testGetPackageInfoForSdk_systemOrShell()1163 public void testGetPackageInfoForSdk_systemOrShell() throws Exception { 1164 onBeforeSdkTests(); 1165 1166 installPackage(TEST_SDK1); 1167 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1168 1169 // Access as a shell 1170 SystemUtil.runWithShellPermissionIdentity(() -> { 1171 PackageInfo info = getPackageManager().getPackageInfo(TEST_SDK1_PACKAGE, 1172 PackageManager.PackageInfoFlags.of(MATCH_STATIC_SHARED_AND_SDK_LIBRARIES)); 1173 1174 assertThat(info).isNotNull(); 1175 assertThat(info.packageName).isEqualTo(TEST_SDK1_PACKAGE); 1176 }); 1177 } 1178 1179 @Test testGetApplicationInfoForSdk_systemOrShell()1180 public void testGetApplicationInfoForSdk_systemOrShell() throws Exception { 1181 onBeforeSdkTests(); 1182 1183 installPackage(TEST_SDK1); 1184 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1185 1186 // Access as a shell 1187 SystemUtil.runWithShellPermissionIdentity(() -> { 1188 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK1_PACKAGE, 1189 PackageManager.ApplicationInfoFlags.of( 1190 MATCH_STATIC_SHARED_AND_SDK_LIBRARIES)); 1191 1192 assertThat(appInfo).isNotNull(); 1193 assertThat(appInfo.icon).isGreaterThan(0); 1194 1195 assertThat(appInfo.targetSdkVersion).isEqualTo(34); 1196 assertThat(appInfo.minSdkVersion).isEqualTo(30); 1197 }); 1198 } 1199 1200 @Test testSharedLibraryAccess_systemOrShell()1201 public void testSharedLibraryAccess_systemOrShell() throws Exception { 1202 onBeforeSdkTests(); 1203 1204 installPackage(TEST_SDK1); 1205 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1206 1207 // Access as a shell 1208 SystemUtil.runWithShellPermissionIdentity(() -> { 1209 List<SharedLibraryInfo> shareLibs = getPackageManager().getSharedLibraries(/*flags=*/ 1210 0); 1211 SharedLibraryInfo sdk = findLibrary(shareLibs, TEST_SDK1_NAME, 1); 1212 assertThat(sdk).isNotNull(); 1213 }); 1214 } 1215 1216 @Test testGetProperty()1217 public void testGetProperty() throws Exception { 1218 onBeforeSdkTests(); 1219 1220 installPackage(TEST_SDK1); 1221 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1222 1223 PackageManager.Property property = 1224 getPackageManager().getProperty("com.test.sdk1_1.TEST_PROPERTY", 1225 TEST_SDK1_PACKAGE); 1226 assertThat(property).isNotNull(); 1227 assertThat(property.getName()).isEqualTo("com.test.sdk1_1.TEST_PROPERTY"); 1228 assertThat(property.getString()).isEqualTo("com.test.sdk1_1.testp1"); 1229 } 1230 1231 @Test 1232 @RequiresFlagsEnabled(Flags.FLAG_DISALLOW_SDK_LIBS_TO_BE_APPS) testSdkBlockSdkLibsBeAppsNoComponentRegistered()1233 public void testSdkBlockSdkLibsBeAppsNoComponentRegistered() throws Exception { 1234 onBeforeSdkTests(); 1235 1236 installPackage(TEST_SDK1); 1237 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1238 1239 // Check Activity 1240 Intent intent1 = new Intent(); 1241 intent1.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".MainActivity"); 1242 List<ResolveInfo> resolveInfoList1 = 1243 getPackageManager().queryIntentActivities(intent1, 0); 1244 1245 assertThat(resolveInfoList1).isEmpty(); 1246 1247 // Check Service 1248 Intent intent2 = new Intent(); 1249 intent2.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".FakeService"); 1250 List<ResolveInfo> resolveInfoList2 = 1251 getPackageManager().queryIntentServices(intent2, 0); 1252 1253 assertThat(resolveInfoList2).isEmpty(); 1254 1255 // Check Receiver 1256 Intent intent3 = new Intent(); 1257 intent3.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".FakeReceiver"); 1258 List<ResolveInfo> resolveInfoList3 = 1259 getPackageManager().queryBroadcastReceivers(intent3, 0); 1260 1261 assertThat(resolveInfoList3).isEmpty(); 1262 1263 // Check Provider 1264 Intent intent4 = new Intent(); 1265 intent4.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".FakeProvider"); 1266 List<ResolveInfo> resolveInfoList4 = 1267 getPackageManager().queryIntentContentProviders(intent4, 0); 1268 1269 assertThat(resolveInfoList4).isEmpty(); 1270 } 1271 1272 @Test 1273 @RequiresFlagsDisabled(Flags.FLAG_DISALLOW_SDK_LIBS_TO_BE_APPS) testSdkLibsBeAppsComponentRegistered()1274 public void testSdkLibsBeAppsComponentRegistered() throws Exception { 1275 onBeforeSdkTests(); 1276 1277 installPackage(TEST_SDK1); 1278 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1279 1280 // Check Activity 1281 Intent intent1 = new Intent(); 1282 intent1.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".MainActivity"); 1283 List<ResolveInfo> resolveInfoList1 = 1284 getPackageManager().queryIntentActivities(intent1, 0); 1285 1286 assertThat(resolveInfoList1).isNotEmpty(); 1287 assertThat(resolveInfoList1.size()).isEqualTo(1); 1288 1289 // Check Service 1290 Intent intent2 = new Intent(); 1291 intent2.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".FakeService"); 1292 List<ResolveInfo> resolveInfoList2 = 1293 getPackageManager().queryIntentServices(intent2, 0); 1294 1295 assertThat(resolveInfoList2).isNotEmpty(); 1296 assertThat(resolveInfoList2.size()).isEqualTo(1); 1297 1298 // Check Receiver 1299 Intent intent3 = new Intent(); 1300 intent3.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".FakeReceiver"); 1301 List<ResolveInfo> resolveInfoList3 = 1302 getPackageManager().queryBroadcastReceivers(intent3, 0); 1303 1304 assertThat(resolveInfoList3).isNotEmpty(); 1305 assertThat(resolveInfoList3.size()).isEqualTo(1); 1306 1307 // Check Provider 1308 Intent intent4 = new Intent(); 1309 intent4.setClassName(TEST_SDK1_PACKAGE, TEST_SDK1_PACKAGE + ".FakeProvider"); 1310 List<ResolveInfo> resolveInfoList4 = 1311 getPackageManager().queryIntentContentProviders(intent4, 0); 1312 1313 assertThat(resolveInfoList4).isNotEmpty(); 1314 assertThat(resolveInfoList4.size()).isEqualTo(1); 1315 } 1316 1317 @Test testSdkInstallMultipleMajorVersions()1318 public void testSdkInstallMultipleMajorVersions() throws Exception { 1319 onBeforeSdkTests(); 1320 1321 // Major version 1. 1322 installPackage(TEST_SDK1); 1323 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1324 1325 // Major version 2. 1326 installPackage(TEST_SDK1_MAJOR_VERSION2); 1327 1328 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1329 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 2)); 1330 } 1331 1332 @Test testSdkInstallMultipleMinorVersionsWrongSignature()1333 public void testSdkInstallMultipleMinorVersionsWrongSignature() throws Exception { 1334 onBeforeSdkTests(); 1335 1336 // Major version 1. 1337 installPackage(TEST_SDK1); 1338 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1339 1340 // Major version 1, different signer. 1341 installPackage(TEST_SDK1_DIFFERENT_SIGNER, 1342 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package com.test.sdk1_1 " 1343 + "signatures do not match newer version"); 1344 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1345 } 1346 1347 @Test testSdkInstallMultipleMajorVersionsWrongSignature()1348 public void testSdkInstallMultipleMajorVersionsWrongSignature() throws Exception { 1349 onBeforeSdkTests(); 1350 1351 // Major version 1. 1352 installPackage(TEST_SDK1_DIFFERENT_SIGNER); 1353 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1354 1355 // Major version 2. 1356 installPackage(TEST_SDK1_MAJOR_VERSION2, 1357 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package com.test.sdk1_1 " 1358 + "signatures do not match newer version"); 1359 1360 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1361 } 1362 1363 @Test testSdkInstallAndUpdateTwoMajorVersions()1364 public void testSdkInstallAndUpdateTwoMajorVersions() throws Exception { 1365 onBeforeSdkTests(); 1366 1367 installPackage(TEST_SDK1); 1368 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1369 1370 installPackage(TEST_SDK2); 1371 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1372 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1373 1374 // Same APK. 1375 installPackage(TEST_SDK1); 1376 installPackage(TEST_SDK2); 1377 1378 // Updated APK. 1379 installPackage(TEST_SDK1_UPDATED); 1380 installPackage(TEST_SDK2_UPDATED); 1381 1382 // Reverted APK. 1383 installPackage(TEST_SDK1); 1384 installPackage(TEST_SDK2); 1385 1386 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1387 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1388 } 1389 1390 @Test 1391 @RequiresFlagsEnabled(FLAG_SDK_LIB_INDEPENDENCE) testAppUsingSdkOptionalInstallInstall_allowAppInstallWithoutSDK()1392 public void testAppUsingSdkOptionalInstallInstall_allowAppInstallWithoutSDK() 1393 throws Exception { 1394 onBeforeSdkTests(); 1395 1396 // Try to install without required SDK1. 1397 installPackage(TEST_USING_SDK1_OPTIONAL); 1398 assertTrue(isAppInstalled(TEST_SDK_USER_PACKAGE)); 1399 } 1400 1401 @Test 1402 @RequiresFlagsDisabled(FLAG_SDK_LIB_INDEPENDENCE) testAppUsingSdkOptionalInstall_blockAppInstallWithoutSDK()1403 public void testAppUsingSdkOptionalInstall_blockAppInstallWithoutSDK() throws Exception { 1404 onBeforeSdkTests(); 1405 1406 // Try to install without required SDK1. 1407 installPackage(TEST_USING_SDK1_OPTIONAL, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1408 assertFalse(isAppInstalled(TEST_SDK_USER_PACKAGE)); 1409 } 1410 1411 @Test testAppUsingSdkRequiredInstallAndUpdate()1412 public void testAppUsingSdkRequiredInstallAndUpdate() throws Exception { 1413 onBeforeSdkTests(); 1414 // Try to install without required SDK1. 1415 installPackage(TEST_USING_SDK1, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1416 assertFalse(isAppInstalled(TEST_SDK_USER_PACKAGE)); 1417 1418 // Now install the required SDK1. 1419 installPackage(TEST_SDK1); 1420 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1421 1422 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1423 1424 // Install and uninstall. 1425 installPackage(TEST_USING_SDK1); 1426 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1427 1428 // Update SDK1. 1429 installPackage(TEST_SDK1_UPDATED); 1430 1431 // Install again. 1432 installPackage(TEST_USING_SDK1); 1433 1434 // Check resolution API. 1435 getUiAutomation().adoptShellPermissionIdentity(); 1436 try { 1437 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK_USER_PACKAGE, 1438 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1439 assertEquals(1, appInfo.sharedLibraryInfos.size()); 1440 SharedLibraryInfo libInfo = appInfo.sharedLibraryInfos.get(0); 1441 assertEquals("com.test.sdk1", libInfo.getName()); 1442 assertEquals(1, libInfo.getLongVersion()); 1443 } finally { 1444 getUiAutomation().dropShellPermissionIdentity(); 1445 } 1446 1447 // Try to install without required SDK2. 1448 installPackage(TEST_USING_SDK1_AND_SDK2, 1449 "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1450 1451 // Now install the required SDK2. 1452 installPackage(TEST_SDK2); 1453 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1454 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1455 1456 // Install and uninstall. 1457 installPackage(TEST_USING_SDK1_AND_SDK2); 1458 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1459 1460 // Update both SDKs. 1461 installPackage(TEST_SDK1_UPDATED); 1462 installPackage(TEST_SDK2_UPDATED); 1463 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1464 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1465 1466 // Install again. 1467 installPackage(TEST_USING_SDK1_AND_SDK2); 1468 1469 // Check resolution API. 1470 getUiAutomation().adoptShellPermissionIdentity(); 1471 try { 1472 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK_USER_PACKAGE, 1473 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1474 assertEquals(2, appInfo.sharedLibraryInfos.size()); 1475 assertEquals("com.test.sdk1", appInfo.sharedLibraryInfos.get(0).getName()); 1476 assertEquals(1, appInfo.sharedLibraryInfos.get(0).getLongVersion()); 1477 assertEquals("com.test.sdk2", appInfo.sharedLibraryInfos.get(1).getName()); 1478 assertEquals(2, appInfo.sharedLibraryInfos.get(1).getLongVersion()); 1479 } finally { 1480 getUiAutomation().dropShellPermissionIdentity(); 1481 } 1482 } 1483 1484 @Test testAppUsingSdkRequiredInstallGroupInstall()1485 public void testAppUsingSdkRequiredInstallGroupInstall() throws Exception { 1486 onBeforeSdkTests(); 1487 1488 // Install/uninstall the sdk to grab its certDigest. 1489 installPackage(TEST_SDK1); 1490 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1491 String sdkCertDigest = getPackageCertDigest(TEST_SDK1_PACKAGE); 1492 uninstallPackageSilently(TEST_SDK1_PACKAGE); 1493 1494 // Try to install without required SDK1. 1495 installPackage(TEST_USING_SDK1, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1496 assertFalse(isAppInstalled(TEST_SDK_USER_PACKAGE)); 1497 1498 // Parent session 1499 String parentSessionId = createSession("--multi-package"); 1500 1501 // Required SDK1. 1502 String sdkSessionId = createSession(""); 1503 addSplits(sdkSessionId, new String[] { createApkPath(TEST_SDK1) }); 1504 1505 // The app. 1506 String appSessionId = createSession(""); 1507 addSplits(appSessionId, new String[] { createApkPath(TEST_USING_SDK1) }); 1508 1509 overrideUsesSdkLibraryCertificateDigest(sdkCertDigest); 1510 1511 // Add both child sessions to the primary session and commit. 1512 assertEquals("Success\n", executeShellCommand( 1513 "pm install-add-session " + parentSessionId + " " + sdkSessionId + " " 1514 + appSessionId)); 1515 commitSession(parentSessionId); 1516 1517 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1518 assertTrue(isAppInstalled(TEST_SDK_USER_PACKAGE)); 1519 1520 // Check resolution API. 1521 getUiAutomation().adoptShellPermissionIdentity(); 1522 try { 1523 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK_USER_PACKAGE, 1524 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1525 assertEquals(1, appInfo.sharedLibraryInfos.size()); 1526 SharedLibraryInfo libInfo = appInfo.sharedLibraryInfos.get(0); 1527 assertEquals("com.test.sdk1", libInfo.getName()); 1528 assertEquals(1, libInfo.getLongVersion()); 1529 } finally { 1530 getUiAutomation().dropShellPermissionIdentity(); 1531 } 1532 } 1533 1534 @Test testInstallSdkFailsMismatchingCertificate()1535 public void testInstallSdkFailsMismatchingCertificate() throws Exception { 1536 onBeforeSdkTests(); 1537 1538 // Install the required SDK1. 1539 installPackage(TEST_SDK1); 1540 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1541 1542 // Try to install the package with empty digest. 1543 installPackage(TEST_USING_SDK1, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1544 } 1545 1546 @Test testUninstallSdkRequiredWhileAppUsing_blockUninstall()1547 public void testUninstallSdkRequiredWhileAppUsing_blockUninstall() throws Exception { 1548 onBeforeSdkTests(); 1549 1550 // Install the required SDK1. 1551 installPackage(TEST_SDK1); 1552 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1553 1554 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1555 1556 // Install the package. 1557 installPackage(TEST_USING_SDK1); 1558 1559 uninstallPackage(TEST_SDK1_PACKAGE, "Failure [DELETE_FAILED_USED_SHARED_LIBRARY]"); 1560 1561 // The SDK is still installed 1562 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1563 } 1564 1565 @Test 1566 @RequiresFlagsEnabled(FLAG_SDK_LIB_INDEPENDENCE) testUninstallSdkOptionalWhileAppUsing_allowUninstall()1567 public void testUninstallSdkOptionalWhileAppUsing_allowUninstall() throws Exception { 1568 onBeforeSdkTests(); 1569 1570 // Install the required SDK1. 1571 installPackage(TEST_SDK1); 1572 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1573 1574 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1575 1576 // Install the package optional using sdk1 1577 installPackage(TEST_USING_SDK1_OPTIONAL); 1578 1579 uninstallPackage(TEST_SDK1_PACKAGE, "Success"); 1580 assertThat(isSdkInstalled(TEST_SDK1_NAME, 1)).isFalse(); 1581 } 1582 1583 @Test 1584 @RequiresFlagsEnabled(FLAG_SDK_LIB_INDEPENDENCE) testSdkOptionalEnabledGetSharedLibraries()1585 public void testSdkOptionalEnabledGetSharedLibraries() throws Exception { 1586 onBeforeSdkTests(); 1587 1588 // Install the SDK1. 1589 installPackage(TEST_SDK1); 1590 // Install the SDK2. 1591 installPackage(TEST_SDK2); 1592 1593 { 1594 List<SharedLibraryInfo> libs = getSharedLibraries(); 1595 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1596 assertNotNull(sdk1); 1597 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1598 assertNotNull(sdk2); 1599 } 1600 { 1601 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1602 1603 installPackage(TEST_USING_SDK1_OPTIONAL_SDK2); 1604 1605 List<SharedLibraryInfo> libs = getSharedLibraries(); 1606 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1607 assertNotNull(sdk1); 1608 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1609 assertNotNull(sdk2); 1610 1611 // SDK1 optional 1612 assertEquals(TEST_SDK_USER_PACKAGE, 1613 sdk1.getDependentPackages().get(0).getPackageName()); 1614 assertEquals(TEST_SDK_USER_PACKAGE, 1615 sdk1.getOptionalDependentPackages().get(0).getPackageName()); 1616 1617 // SDK2 required 1618 assertEquals(TEST_SDK_USER_PACKAGE, 1619 sdk2.getDependentPackages().get(0).getPackageName()); 1620 assertThat(sdk2.getOptionalDependentPackages()).isEmpty(); 1621 1622 getUiAutomation().adoptShellPermissionIdentity(); 1623 try { 1624 ApplicationInfo appInfo = getPackageManager().getApplicationInfo( 1625 TEST_SDK_USER_PACKAGE, 1626 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1627 1628 // feature is enabled. Two, one is optional, one is required 1629 assertThat(appInfo.sharedLibraryInfos).isNotNull(); 1630 assertThat(appInfo.optionalSharedLibraryInfos).isNotNull(); 1631 assertThat(appInfo.sharedLibraryInfos.size()).isEqualTo(2); 1632 assertThat(appInfo.optionalSharedLibraryInfos.size()).isEqualTo(1); 1633 1634 assertThat(appInfo.optionalSharedLibraryInfos.get(0).getName()).isEqualTo( 1635 "com.test.sdk1"); 1636 assertThat(appInfo.optionalSharedLibraryInfos.get(0).getLongVersion()).isEqualTo(1); 1637 1638 assertThat(appInfo.sharedLibraryInfos.get(0).getName()).isEqualTo( 1639 "com.test.sdk1"); 1640 assertThat(appInfo.sharedLibraryInfos.get(0).getLongVersion()).isEqualTo(1); 1641 assertThat(appInfo.sharedLibraryInfos.get(1).getName()).isEqualTo( 1642 "com.test.sdk2"); 1643 assertThat(appInfo.sharedLibraryInfos.get(1).getLongVersion()).isEqualTo(2); 1644 } finally { 1645 getUiAutomation().dropShellPermissionIdentity(); 1646 } 1647 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1648 } 1649 } 1650 1651 @Test 1652 @RequiresFlagsDisabled(FLAG_SDK_LIB_INDEPENDENCE) testSdkOptionalDisabledGetSharedLibraries()1653 public void testSdkOptionalDisabledGetSharedLibraries() throws Exception { 1654 onBeforeSdkTests(); 1655 1656 // Install the SDK1. 1657 installPackage(TEST_SDK1); 1658 // Install the SDK2. 1659 installPackage(TEST_SDK2); 1660 1661 { 1662 List<SharedLibraryInfo> libs = getSharedLibraries(); 1663 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1664 assertNotNull(sdk1); 1665 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1666 assertNotNull(sdk2); 1667 } 1668 1669 { 1670 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1671 1672 installPackage(TEST_USING_SDK1_OPTIONAL_SDK2); 1673 1674 List<SharedLibraryInfo> libs = getSharedLibraries(); 1675 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1676 assertNotNull(sdk1); 1677 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1678 assertNotNull(sdk2); 1679 1680 assertEquals(TEST_SDK_USER_PACKAGE, 1681 sdk1.getDependentPackages().get(0).getPackageName()); 1682 assertEquals(TEST_SDK_USER_PACKAGE, 1683 sdk2.getDependentPackages().get(0).getPackageName()); 1684 assertThat(sdk1.getOptionalDependentPackages()).isEmpty(); 1685 assertThat(sdk2.getOptionalDependentPackages()).isEmpty(); 1686 1687 1688 getUiAutomation().adoptShellPermissionIdentity(); 1689 try { 1690 ApplicationInfo appInfo = getPackageManager().getApplicationInfo( 1691 TEST_SDK_USER_PACKAGE, 1692 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1693 1694 // Two, one is optional, one is required but feature is disabled 1695 assertThat(appInfo.sharedLibraryInfos).isNotNull(); 1696 assertThat(appInfo.optionalSharedLibraryInfos).isNull(); 1697 assertThat(appInfo.sharedLibraryInfos.size()).isEqualTo(2); 1698 1699 assertThat(appInfo.sharedLibraryInfos.get(0).getName()).isEqualTo( 1700 "com.test.sdk1"); 1701 assertThat(appInfo.sharedLibraryInfos.get(0).getLongVersion()).isEqualTo(1); 1702 1703 assertThat(appInfo.sharedLibraryInfos.get(1).getName()).isEqualTo( 1704 "com.test.sdk2"); 1705 assertThat(appInfo.sharedLibraryInfos.get(1).getLongVersion()).isEqualTo(2); 1706 } finally { 1707 getUiAutomation().dropShellPermissionIdentity(); 1708 } 1709 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1710 } 1711 } 1712 1713 @Test testGetSharedLibraries()1714 public void testGetSharedLibraries() throws Exception { 1715 onBeforeSdkTests(); 1716 1717 // Install the SDK1. 1718 installPackage(TEST_SDK1); 1719 { 1720 List<SharedLibraryInfo> libs = getSharedLibraries(); 1721 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1722 assertNotNull(sdk1); 1723 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1724 assertNull(sdk2); 1725 } 1726 1727 // Install the SDK2. 1728 installPackage(TEST_SDK2); 1729 { 1730 List<SharedLibraryInfo> libs = getSharedLibraries(); 1731 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1732 assertNotNull(sdk1); 1733 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1734 assertNotNull(sdk2); 1735 } 1736 1737 // Install and uninstall the user package. 1738 { 1739 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1740 1741 installPackage(TEST_USING_SDK1_AND_SDK2); 1742 1743 List<SharedLibraryInfo> libs = getSharedLibraries(); 1744 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1745 assertNotNull(sdk1); 1746 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1747 assertNotNull(sdk2); 1748 1749 assertEquals(TEST_SDK_USER_PACKAGE, 1750 sdk1.getDependentPackages().get(0).getPackageName()); 1751 assertEquals(TEST_SDK_USER_PACKAGE, 1752 sdk2.getDependentPackages().get(0).getPackageName()); 1753 assertThat(sdk1.getOptionalDependentPackages()).isEmpty(); 1754 assertThat(sdk2.getOptionalDependentPackages()).isEmpty(); 1755 1756 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1757 } 1758 1759 // Uninstall the SDK1. 1760 uninstallPackageSilently(TEST_SDK1_PACKAGE); 1761 { 1762 List<SharedLibraryInfo> libs = getSharedLibraries(); 1763 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1764 assertNull(sdk1); 1765 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1766 assertNotNull(sdk2); 1767 } 1768 1769 // Uninstall the SDK2. 1770 uninstallPackageSilently(TEST_SDK2_PACKAGE); 1771 { 1772 List<SharedLibraryInfo> libs = getSharedLibraries(); 1773 SharedLibraryInfo sdk1 = findLibrary(libs, "com.test.sdk1", 1); 1774 assertNull(sdk1); 1775 SharedLibraryInfo sdk2 = findLibrary(libs, "com.test.sdk2", 2); 1776 assertNull(sdk2); 1777 } 1778 } 1779 1780 @Test testUninstallUnusedSdks()1781 public void testUninstallUnusedSdks() throws Exception { 1782 onBeforeSdkTests(); 1783 1784 installPackage(TEST_SDK1); 1785 installPackage(TEST_SDK2); 1786 1787 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1788 installPackage(TEST_USING_SDK1_AND_SDK2); 1789 1790 setSystemProperty("debug.pm.prune_unused_shared_libraries_delay", "0"); 1791 executeShellCommand("settings put global unused_static_shared_lib_min_cache_period 0"); 1792 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1793 1794 // Wait for 3secs max. 1795 for (int i = 0; i < 30; ++i) { 1796 if (!isSdkInstalled(TEST_SDK1_NAME, 1) && !isSdkInstalled(TEST_SDK2_NAME, 2)) { 1797 break; 1798 } 1799 final int beforeRetryDelayMs = 100; 1800 Thread.currentThread().sleep(beforeRetryDelayMs); 1801 } 1802 assertFalse(isSdkInstalled(TEST_SDK1_NAME, 1)); 1803 assertFalse(isSdkInstalled(TEST_SDK2_NAME, 2)); 1804 } 1805 1806 @Test testAppUsingSdkRequiredUsingSdkInstallAndUpdate()1807 public void testAppUsingSdkRequiredUsingSdkInstallAndUpdate() throws Exception { 1808 onBeforeSdkTests(); 1809 1810 // Try to install without required SDK1. 1811 installPackage(TEST_USING_SDK3, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1812 assertFalse(isAppInstalled(TEST_SDK_USER_PACKAGE)); 1813 1814 // Try to install SDK3 without required SDK1. 1815 installPackage(TEST_SDK3_USING_SDK1, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1816 assertFalse(isSdkInstalled(TEST_SDK3_NAME, 3)); 1817 1818 // Now install the required SDK1. 1819 installPackage(TEST_SDK1); 1820 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1821 1822 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1823 1824 // Now install the required SDK3. 1825 installPackage(TEST_SDK3_USING_SDK1); 1826 assertTrue(isSdkInstalled(TEST_SDK3_NAME, 3)); 1827 1828 // Install and uninstall. 1829 installPackage(TEST_USING_SDK3); 1830 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1831 1832 // Update SDK1. 1833 installPackage(TEST_SDK1_UPDATED); 1834 1835 // Install again. 1836 installPackage(TEST_USING_SDK3); 1837 1838 // Check resolution API. 1839 getUiAutomation().adoptShellPermissionIdentity(); 1840 try { 1841 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK_USER_PACKAGE, 1842 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1843 assertEquals(1, appInfo.sharedLibraryInfos.size()); 1844 SharedLibraryInfo libInfo = appInfo.sharedLibraryInfos.get(0); 1845 assertEquals("com.test.sdk3", libInfo.getName()); 1846 assertEquals(3, libInfo.getLongVersion()); 1847 } finally { 1848 getUiAutomation().dropShellPermissionIdentity(); 1849 } 1850 1851 // Try to install updated SDK3 without required SDK2. 1852 installPackage(TEST_SDK3_USING_SDK1_AND_SDK2, 1853 "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1854 1855 // Now install the required SDK2. 1856 installPackage(TEST_SDK2); 1857 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1858 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1859 1860 installPackage(TEST_SDK3_USING_SDK1_AND_SDK2); 1861 assertTrue(isSdkInstalled(TEST_SDK3_NAME, 3)); 1862 1863 // Install and uninstall. 1864 installPackage(TEST_USING_SDK3); 1865 uninstallPackageSilently(TEST_SDK_USER_PACKAGE); 1866 1867 // Update both SDKs. 1868 installPackage(TEST_SDK1_UPDATED); 1869 installPackage(TEST_SDK2_UPDATED); 1870 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1871 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1872 1873 // Install again. 1874 installPackage(TEST_USING_SDK3); 1875 1876 // Check resolution API. 1877 getUiAutomation().adoptShellPermissionIdentity(); 1878 try { 1879 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_SDK_USER_PACKAGE, 1880 PackageManager.ApplicationInfoFlags.of(GET_SHARED_LIBRARY_FILES)); 1881 assertEquals(1, appInfo.sharedLibraryInfos.size()); 1882 assertEquals("com.test.sdk3", appInfo.sharedLibraryInfos.get(0).getName()); 1883 assertEquals(3, appInfo.sharedLibraryInfos.get(0).getLongVersion()); 1884 } finally { 1885 getUiAutomation().dropShellPermissionIdentity(); 1886 } 1887 } 1888 1889 @Test testSdkUsingSdkRequiredInstallAndUpdate()1890 public void testSdkUsingSdkRequiredInstallAndUpdate() throws Exception { 1891 onBeforeSdkTests(); 1892 1893 // Try to install without required SDK1. 1894 installPackage(TEST_SDK3_USING_SDK1, "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1895 assertFalse(isSdkInstalled(TEST_SDK3_NAME, 3)); 1896 1897 // Now install the required SDK1. 1898 installPackage(TEST_SDK1); 1899 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1900 1901 overrideUsesSdkLibraryCertificateDigest(getPackageCertDigest(TEST_SDK1_PACKAGE)); 1902 1903 // Install and uninstall. 1904 installPackage(TEST_SDK3_USING_SDK1); 1905 uninstallPackageSilently(TEST_SDK3_PACKAGE); 1906 1907 // Update SDK1. 1908 installPackage(TEST_SDK1_UPDATED); 1909 1910 // Install again. 1911 installPackage(TEST_SDK3_USING_SDK1); 1912 1913 // Check resolution API. 1914 { 1915 List<SharedLibraryInfo> libs = getSharedLibraries(); 1916 SharedLibraryInfo sdk3 = findLibrary(libs, "com.test.sdk3", 3); 1917 assertNotNull(sdk3); 1918 List<SharedLibraryInfo> deps = sdk3.getDependencies(); 1919 assertEquals(1, deps.size()); 1920 SharedLibraryInfo libInfo = deps.get(0); 1921 assertEquals("com.test.sdk1", libInfo.getName()); 1922 assertEquals(1, libInfo.getLongVersion()); 1923 } 1924 1925 // Try to install without required SDK2. 1926 installPackage(TEST_SDK3_USING_SDK1_AND_SDK2, 1927 "Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY"); 1928 1929 // Now install the required SDK2. 1930 installPackage(TEST_SDK2); 1931 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1932 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1933 1934 // Install and uninstall. 1935 installPackage(TEST_SDK3_USING_SDK1_AND_SDK2); 1936 uninstallPackageSilently(TEST_SDK3_PACKAGE); 1937 1938 // Update both SDKs. 1939 installPackage(TEST_SDK1_UPDATED); 1940 installPackage(TEST_SDK2_UPDATED); 1941 assertTrue(isSdkInstalled(TEST_SDK1_NAME, 1)); 1942 assertTrue(isSdkInstalled(TEST_SDK2_NAME, 2)); 1943 1944 // Install again. 1945 installPackage(TEST_SDK3_USING_SDK1_AND_SDK2); 1946 1947 // Check resolution API. 1948 { 1949 List<SharedLibraryInfo> libs = getSharedLibraries(); 1950 SharedLibraryInfo sdk3 = findLibrary(libs, "com.test.sdk3", 3); 1951 assertNotNull(sdk3); 1952 List<SharedLibraryInfo> deps = sdk3.getDependencies(); 1953 assertEquals(2, deps.size()); 1954 assertEquals("com.test.sdk1", deps.get(0).getName()); 1955 assertEquals(1, deps.get(0).getLongVersion()); 1956 assertEquals("com.test.sdk2", deps.get(1).getName()); 1957 assertEquals(2, deps.get(1).getLongVersion()); 1958 } 1959 } 1960 runPackageVerifierTest(BiConsumer<Context, Intent> onBroadcast)1961 private void runPackageVerifierTest(BiConsumer<Context, Intent> onBroadcast) 1962 throws Exception { 1963 runPackageVerifierTest(TEST_HW5, TEST_HW7, "Success", onBroadcast); 1964 } 1965 runPackageVerifierTest(String expectedResultStartsWith, BiConsumer<Context, Intent> onBroadcast)1966 private void runPackageVerifierTest(String expectedResultStartsWith, 1967 BiConsumer<Context, Intent> onBroadcast) throws Exception { 1968 runPackageVerifierTest(TEST_HW5, TEST_HW7, expectedResultStartsWith, onBroadcast); 1969 } 1970 runPackageVerifierTest(String baseName, String updatedName, String expectedResultStartsWith, BiConsumer<Context, Intent> onBroadcast)1971 private void runPackageVerifierTest(String baseName, String updatedName, 1972 String expectedResultStartsWith, BiConsumer<Context, Intent> onBroadcast) 1973 throws Exception { 1974 AtomicReference<Thread> onBroadcastThread = new AtomicReference<>(); 1975 1976 runPackageVerifierTestSync(baseName, updatedName, expectedResultStartsWith, 1977 (context, intent) -> { 1978 Thread thread = new Thread(() -> onBroadcast.accept(context, intent)); 1979 thread.start(); 1980 onBroadcastThread.set(thread); 1981 }); 1982 1983 final Thread thread = onBroadcastThread.get(); 1984 if (thread != null) { 1985 thread.join(); 1986 } 1987 } 1988 runPackageVerifierTestSync(String baseName, String updatedName, String expectedResultStartsWith, BiConsumer<Context, Intent> onBroadcast)1989 private void runPackageVerifierTestSync(String baseName, String updatedName, 1990 String expectedResultStartsWith, BiConsumer<Context, Intent> onBroadcast) 1991 throws Exception { 1992 // Install a package. 1993 installPackage(baseName); 1994 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 1995 1996 getUiAutomation().adoptShellPermissionIdentity( 1997 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 1998 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 1999 2000 final CompletableFuture<Boolean> broadcastReceived = new CompletableFuture<>(); 2001 2002 // Create a single-use broadcast receiver 2003 BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 2004 @Override 2005 public void onReceive(Context context, Intent intent) { 2006 context.unregisterReceiver(this); 2007 onBroadcast.accept(context, intent); 2008 broadcastReceived.complete(true); 2009 } 2010 }; 2011 // Create an intent-filter and register the receiver 2012 IntentFilter intentFilter = new IntentFilter(); 2013 intentFilter.addAction(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2014 intentFilter.addDataType(PACKAGE_MIME_TYPE); 2015 // The broadcast is sent for user 0, so we need to request it for all users. 2016 // TODO(b/232317379) Fix this in proper way 2017 getContext().registerReceiverForAllUsers(broadcastReceiver, intentFilter, null, null, 2018 RECEIVER_EXPORTED); 2019 2020 // Enable verification. 2021 executeShellCommand("settings put global verifier_verify_adb_installs 1"); 2022 // Override verifier for updates of debuggable apps. 2023 setSystemProperty("debug.pm.adb_verifier_override_packages", 2024 CTS_PACKAGE_NAME + ";" + TEST_VERIFIER_PACKAGE); 2025 2026 final int settingValue = Integer.parseInt( 2027 executeShellCommand("settings get global verifier_verify_adb_installs").trim()); 2028 final String sysPropertyValue = getSystemProperty( 2029 "debug.pm.adb_verifier_override_packages").trim(); 2030 // Make sure the setting and property are set 2031 assertEquals("verifier_verify_adb_installs is " + settingValue + " expecting 1", 2032 1, settingValue); 2033 assertEquals("debug.pm.adb_verifier_override_packages is " + sysPropertyValue, 2034 CTS_PACKAGE_NAME + ";" + TEST_VERIFIER_PACKAGE, sysPropertyValue); 2035 2036 // Update the package, should trigger verifier override. 2037 installPackage(updatedName, expectedResultStartsWith); 2038 2039 // Wait for broadcast. 2040 broadcastReceived.get(VERIFICATION_BROADCAST_RECEIVED_TIMEOUT_MS, TimeUnit.MILLISECONDS); 2041 } 2042 2043 @Test 2044 @LargeTest testPackageVerifierAllow()2045 public void testPackageVerifierAllow() throws Exception { 2046 assumeTrue(!mStreaming); 2047 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2048 2049 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2050 2051 runPackageVerifierTest((context, intent) -> { 2052 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2053 assertNotEquals(-1, verificationId); 2054 2055 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2056 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2057 assertNotEquals(-1, sessionId); 2058 2059 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2060 }); 2061 2062 assertEquals(mDataLoaderType, dataLoaderType.get()); 2063 } 2064 2065 @Test 2066 @LargeTest testPackageVerifierAllowTwoVerifiers()2067 public void testPackageVerifierAllowTwoVerifiers() throws Exception { 2068 assumeTrue(!mStreaming); 2069 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2070 2071 installPackage(TEST_VERIFIER_ALLOW); 2072 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2073 2074 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2075 2076 runPackageVerifierTest((context, intent) -> { 2077 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2078 assertNotEquals(-1, verificationId); 2079 2080 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2081 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2082 assertNotEquals(-1, sessionId); 2083 2084 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2085 }); 2086 2087 assertEquals(mDataLoaderType, dataLoaderType.get()); 2088 } 2089 2090 @Test 2091 @LargeTest testPackageVerifierReject()2092 public void testPackageVerifierReject() throws Exception { 2093 assumeTrue(!mStreaming); 2094 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2095 2096 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2097 2098 runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2099 (context, intent) -> { 2100 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2101 assertNotEquals(-1, verificationId); 2102 2103 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2104 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2105 assertNotEquals(-1, sessionId); 2106 2107 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_REJECT); 2108 }); 2109 2110 assertEquals(mDataLoaderType, dataLoaderType.get()); 2111 } 2112 2113 @Test 2114 @LargeTest testPackageSufficientVerifierReject()2115 public void testPackageSufficientVerifierReject() throws Exception { 2116 assumeTrue(!mStreaming); 2117 uninstallPackageSilently(TEST_SUFFICIENT_VERIFIER_PACKAGE); 2118 2119 // TEST_SUFFICIENT configured to have hellosufficient as sufficient verifier. 2120 installPackage(TEST_SUFFICIENT_VERIFIER_REJECT); 2121 assertTrue(isAppInstalled(TEST_SUFFICIENT_VERIFIER_PACKAGE)); 2122 2123 // PackageManager.verifyPendingInstall() call only works with user 0 as verifier is expected 2124 // to be user 0. So skip the test if it is not user 0. 2125 // TODO(b/232317379) Fix this in proper way 2126 assumeTrue(getContext().getUserId() == UserHandle.USER_SYSTEM); 2127 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2128 2129 runPackageVerifierTest(TEST_HW5, TEST_SUFFICIENT, 2130 "Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2131 (context, intent) -> { 2132 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2133 assertNotEquals(-1, verificationId); 2134 2135 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2136 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2137 assertNotEquals(-1, sessionId); 2138 2139 // This is a required verifier. The installation should fail, even though the 2140 // required verifier allows installation. 2141 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2142 }); 2143 2144 assertEquals(mDataLoaderType, dataLoaderType.get()); 2145 } 2146 2147 @Test 2148 @LargeTest testPackageVerifierRejectTwoVerifiersBothReject()2149 public void testPackageVerifierRejectTwoVerifiersBothReject() throws Exception { 2150 assumeTrue(!mStreaming); 2151 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2152 2153 installPackage(TEST_VERIFIER_REJECT); 2154 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2155 2156 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2157 2158 runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2159 (context, intent) -> { 2160 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2161 assertNotEquals(-1, verificationId); 2162 2163 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2164 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2165 assertNotEquals(-1, sessionId); 2166 2167 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_REJECT); 2168 }); 2169 2170 assertEquals(mDataLoaderType, dataLoaderType.get()); 2171 } 2172 2173 @Test 2174 @LargeTest testPackageVerifierRejectTwoVerifiersOnlyOneRejects()2175 public void testPackageVerifierRejectTwoVerifiersOnlyOneRejects() throws Exception { 2176 assumeTrue(!mStreaming); 2177 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2178 2179 installPackage(TEST_VERIFIER_REJECT); 2180 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2181 2182 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2183 2184 runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2185 (context, intent) -> { 2186 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2187 assertNotEquals(-1, verificationId); 2188 2189 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2190 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2191 assertNotEquals(-1, sessionId); 2192 2193 // This one allows, the other one rejects. 2194 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2195 }); 2196 2197 assertEquals(mDataLoaderType, dataLoaderType.get()); 2198 } 2199 2200 @Test 2201 @LargeTest testPackageVerifierRejectTwoVerifiersOnlyOneDelayedRejects()2202 public void testPackageVerifierRejectTwoVerifiersOnlyOneDelayedRejects() throws Exception { 2203 assumeTrue(!mStreaming); 2204 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2205 2206 installPackage(TEST_VERIFIER_DELAYED_REJECT); 2207 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2208 2209 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2210 2211 runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2212 (context, intent) -> { 2213 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2214 assertNotEquals(-1, verificationId); 2215 2216 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2217 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2218 assertNotEquals(-1, sessionId); 2219 2220 // This one allows, the other one rejects. 2221 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2222 }); 2223 2224 assertEquals(mDataLoaderType, dataLoaderType.get()); 2225 } 2226 2227 @Test 2228 @LargeTest testPackageVerifierRejectAfterTimeout()2229 public void testPackageVerifierRejectAfterTimeout() throws Exception { 2230 assumeTrue(mVerifierTimeoutTest); 2231 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2232 2233 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2234 2235 runPackageVerifierTestSync(TEST_HW5, TEST_HW7, "Success", (context, intent) -> { 2236 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2237 assertNotEquals(-1, verificationId); 2238 2239 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2240 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2241 assertNotEquals(-1, sessionId); 2242 2243 try { 2244 if (mDataLoaderType == DATA_LOADER_TYPE_INCREMENTAL) { 2245 // For streaming installations, the timeout is fixed at 3secs and always 2246 // allow the install. Try to extend the timeout and then reject after 2247 // much shorter time. 2248 getPackageManager().extendVerificationTimeout(verificationId, 2249 VERIFICATION_REJECT, sStreamingVerificationTimeoutMs * 3); 2250 Thread.sleep(sStreamingVerificationTimeoutMs * 2); 2251 getPackageManager().verifyPendingInstall(verificationId, 2252 VERIFICATION_REJECT); 2253 } else { 2254 getPackageManager().verifyPendingInstall(verificationId, 2255 VERIFICATION_ALLOW); 2256 } 2257 } catch (InterruptedException e) { 2258 throw new RuntimeException(e); 2259 } 2260 }); 2261 2262 assertEquals(mDataLoaderType, dataLoaderType.get()); 2263 } 2264 2265 @Test 2266 @LargeTest testPackageVerifierWithExtensionAndTimeout()2267 public void testPackageVerifierWithExtensionAndTimeout() throws Exception { 2268 assumeTrue(mVerifierTimeoutTest); 2269 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2270 2271 runPackageVerifierTest((context, intent) -> { 2272 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2273 assertNotEquals(-1, verificationId); 2274 2275 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2276 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2277 assertNotEquals(-1, sessionId); 2278 2279 try { 2280 if (mDataLoaderType == DATA_LOADER_TYPE_INCREMENTAL) { 2281 // For streaming installations, the timeout is fixed at 3secs and always 2282 // allow the install. Try to extend the timeout and then reject after 2283 // much shorter time. 2284 getPackageManager().extendVerificationTimeout(verificationId, 2285 VERIFICATION_REJECT, sStreamingVerificationTimeoutMs * 3); 2286 Thread.sleep(sStreamingVerificationTimeoutMs * 2); 2287 getPackageManager().verifyPendingInstall(verificationId, 2288 VERIFICATION_REJECT); 2289 } else { 2290 getPackageManager().verifyPendingInstall(verificationId, 2291 VERIFICATION_ALLOW); 2292 } 2293 } catch (InterruptedException e) { 2294 throw new RuntimeException(e); 2295 } 2296 }); 2297 2298 assertEquals(mDataLoaderType, dataLoaderType.get()); 2299 } 2300 2301 @Test testPackageVerifierWithChecksums()2302 public void testPackageVerifierWithChecksums() throws Exception { 2303 assumeTrue(mVerifierTimeoutTest); 2304 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2305 2306 AtomicInteger dataLoaderType = new AtomicInteger(-1); 2307 List<ApkChecksum> checksums = new ArrayList<>(); 2308 StringBuilder rootHash = new StringBuilder(); 2309 2310 runPackageVerifierTest((context, intent) -> { 2311 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2312 assertNotEquals(-1, verificationId); 2313 2314 dataLoaderType.set(intent.getIntExtra(EXTRA_DATA_LOADER_TYPE, -1)); 2315 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2316 assertNotEquals(-1, sessionId); 2317 2318 try { 2319 PackageInstaller.Session session = getPackageInstaller().openSession(sessionId); 2320 assertNotNull(session); 2321 2322 rootHash.append(intent.getStringExtra(EXTRA_VERIFICATION_ROOT_HASH)); 2323 2324 String[] names = session.getNames(); 2325 assertEquals(1, names.length); 2326 session.requestChecksums(names[0], 0, PackageManager.TRUST_ALL, 2327 ConcurrentUtils.DIRECT_EXECUTOR, 2328 result -> checksums.addAll(result)); 2329 } catch (IOException | CertificateEncodingException e) { 2330 throw new RuntimeException(e); 2331 } 2332 }); 2333 2334 assertEquals(mDataLoaderType, dataLoaderType.get()); 2335 2336 assertEquals(1, checksums.size()); 2337 2338 if (mDataLoaderType == DATA_LOADER_TYPE_INCREMENTAL) { 2339 assertEquals(TYPE_WHOLE_MERKLE_ROOT_4K_SHA256, checksums.get(0).getType()); 2340 assertEquals(rootHash.toString(), 2341 "base.apk:" + HexDump.toHexString(checksums.get(0).getValue())); 2342 } else { 2343 assertEquals(TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256, checksums.get(0).getType()); 2344 } 2345 } 2346 2347 @Test testPackageVerifierWithOneVerifierDisabledAtRunTime()2348 public void testPackageVerifierWithOneVerifierDisabledAtRunTime() throws Exception { 2349 assumeTrue(!mStreaming); 2350 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2351 2352 installPackage(TEST_VERIFIER_REJECT); 2353 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2354 runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2355 (context, intent) -> { 2356 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2357 assertNotEquals(-1, verificationId); 2358 2359 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2360 assertNotEquals(-1, sessionId); 2361 2362 // This one allows, the other one rejects. 2363 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2364 }); 2365 2366 // We can't disable the test package, but we can disable the second verifier package 2367 disablePackage(TEST_VERIFIER_PACKAGE); 2368 // Expect the installation to success, even though the second verifier would reject it 2369 // if the verifier is enabled 2370 runPackageVerifierTest( 2371 (context, intent) -> { 2372 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2373 assertNotEquals(-1, verificationId); 2374 2375 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2376 assertNotEquals(-1, sessionId); 2377 2378 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2379 }); 2380 2381 } 2382 2383 @Test testPackageVerifierWithOneVerifierDisabledAtManifest()2384 public void testPackageVerifierWithOneVerifierDisabledAtManifest() throws Exception { 2385 assumeTrue(!mStreaming); 2386 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2387 2388 // The second verifier package is disabled in its manifest 2389 installPackage(TEST_VERIFIER_REJECT); 2390 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2391 runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed", 2392 (context, intent) -> { 2393 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2394 assertNotEquals(-1, verificationId); 2395 2396 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2397 assertNotEquals(-1, sessionId); 2398 2399 // This one allows, the other one rejects. 2400 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2401 }); 2402 // Uninstall the second verifier first to allow for the new verifier installation 2403 uninstallPackageSilently(TEST_VERIFIER_PACKAGE); 2404 installPackage(TEST_VERIFIER_DISABLED); 2405 assertTrue(isAppInstalled(TEST_VERIFIER_PACKAGE)); 2406 // Expect the installation to success, even though the second verifier would reject it 2407 // if the verifier is enabled 2408 runPackageVerifierTest( 2409 (context, intent) -> { 2410 int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); 2411 assertNotEquals(-1, verificationId); 2412 2413 int sessionId = intent.getIntExtra(EXTRA_SESSION_ID, -1); 2414 assertNotEquals(-1, sessionId); 2415 2416 getPackageManager().verifyPendingInstall(verificationId, VERIFICATION_ALLOW); 2417 }); 2418 2419 } 2420 2421 @Test testEmergencyInstallerNoAttribute()2422 public void testEmergencyInstallerNoAttribute() throws Exception { 2423 installPackage(TEST_INSTALLER_APP_ABSENT); 2424 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 2425 2426 getUiAutomation() 2427 .adoptShellPermissionIdentity(Manifest.permission.EMERGENCY_INSTALL_PACKAGES); 2428 try { 2429 final PackageInstaller installer = getPackageInstaller(); 2430 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2431 params.setAppPackageName(TEST_APP_PACKAGE); 2432 final int sessionId = installer.createSession(params); 2433 PackageInstaller.Session session = installer.openSession(sessionId); 2434 2435 writeFileToSession(session, "installer_app_absent_updated", 2436 TEST_INSTALLER_APP_ABSENT_UPDATED); 2437 2438 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2439 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2440 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 2441 @Override 2442 public void send(int code, Intent intent, String resolvedType, 2443 IBinder whitelistToken, IIntentReceiver finishedReceiver, 2444 String requiredPermission, Bundle options) throws RemoteException { 2445 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2446 Integer.MIN_VALUE)); 2447 statusMessage.complete( 2448 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 2449 } 2450 })); 2451 2452 assertEquals(statusMessage.get(), PackageInstaller.STATUS_PENDING_USER_ACTION, 2453 (int) status.get()); 2454 } finally { 2455 getUiAutomation().dropShellPermissionIdentity(); 2456 } 2457 } 2458 2459 @Test testEmergencyInstallerNoPermission()2460 public void testEmergencyInstallerNoPermission() throws Exception { 2461 installPackage(TEST_INSTALLER_APP); 2462 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 2463 2464 try { 2465 final PackageInstaller installer = getPackageInstaller(); 2466 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2467 params.setAppPackageName(TEST_APP_PACKAGE); 2468 final int sessionId = installer.createSession(params); 2469 PackageInstaller.Session session = installer.openSession(sessionId); 2470 2471 writeFileToSession(session, "installer_app_updated", TEST_INSTALLER_APP_UPDATED); 2472 2473 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2474 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2475 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 2476 @Override 2477 public void send(int code, Intent intent, String resolvedType, 2478 IBinder whitelistToken, IIntentReceiver finishedReceiver, 2479 String requiredPermission, Bundle options) throws RemoteException { 2480 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2481 Integer.MIN_VALUE)); 2482 statusMessage.complete( 2483 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 2484 } 2485 })); 2486 2487 assertEquals(statusMessage.get(), PackageInstaller.STATUS_PENDING_USER_ACTION, 2488 (int) status.get()); 2489 } finally { 2490 getUiAutomation().dropShellPermissionIdentity(); 2491 } 2492 } 2493 2494 // We can't test updating a system app with INSTALL_PACKAGES in CTS tests; this positive test 2495 // will be in GTS tests instead. 2496 @Test testEmergencyInstallerNonSystemApp()2497 public void testEmergencyInstallerNonSystemApp() throws Exception { 2498 installPackage(TEST_INSTALLER_APP); 2499 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 2500 2501 getUiAutomation() 2502 .adoptShellPermissionIdentity(Manifest.permission.EMERGENCY_INSTALL_PACKAGES); 2503 try { 2504 final PackageInstaller installer = getPackageInstaller(); 2505 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2506 params.setAppPackageName(TEST_APP_PACKAGE); 2507 final int sessionId = installer.createSession(params); 2508 PackageInstaller.Session session = installer.openSession(sessionId); 2509 2510 writeFileToSession(session, "installer_app_updated", TEST_INSTALLER_APP_UPDATED); 2511 2512 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2513 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2514 session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() { 2515 @Override 2516 public void send(int code, Intent intent, String resolvedType, 2517 IBinder whitelistToken, IIntentReceiver finishedReceiver, 2518 String requiredPermission, Bundle options) throws RemoteException { 2519 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2520 Integer.MIN_VALUE)); 2521 statusMessage.complete( 2522 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 2523 } 2524 })); 2525 2526 assertEquals(statusMessage.get(), PackageInstaller.STATUS_PENDING_USER_ACTION, 2527 (int) status.get()); 2528 } finally { 2529 getUiAutomation().dropShellPermissionIdentity(); 2530 } 2531 } 2532 2533 @Test testEmergencyInstallerUninstallNoAttribiute()2534 public void testEmergencyInstallerUninstallNoAttribiute() throws Exception { 2535 assumeTrue(mDataLoaderType == DATA_LOADER_TYPE_NONE); 2536 getUiAutomation().adoptShellPermissionIdentity( 2537 Manifest.permission.EMERGENCY_INSTALL_PACKAGES, 2538 Manifest.permission.REQUEST_DELETE_PACKAGES, 2539 Manifest.permission.INSTALL_PACKAGES); 2540 2541 try { 2542 installPackage(TEST_INSTALLER_APP_ABSENT); 2543 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 2544 2545 final PackageInstaller installer = getPackageInstaller(); 2546 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2547 params.setAppPackageName(TEST_APP_PACKAGE); 2548 final int sessionId = installer.createSession(params); 2549 installer.openSession(sessionId); 2550 2551 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2552 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2553 2554 installer.uninstall(TEST_APP_PACKAGE, 2555 new IntentSender((IIntentSender) new IIntentSender.Stub() { 2556 @Override 2557 public void send(int code, Intent intent, String resolvedType, 2558 IBinder whitelistToken, IIntentReceiver finishedReceiver, 2559 String requiredPermission, Bundle options) throws RemoteException { 2560 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2561 Integer.MIN_VALUE)); 2562 statusMessage.complete( 2563 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 2564 } 2565 })); 2566 2567 assertEquals(statusMessage.get(), PackageInstaller.STATUS_PENDING_USER_ACTION, 2568 (int) status.get()); 2569 } finally { 2570 getUiAutomation().dropShellPermissionIdentity(); 2571 } 2572 } 2573 2574 @Test testEmergencyInstallerUninstallNoPermission()2575 public void testEmergencyInstallerUninstallNoPermission() throws Exception { 2576 assumeTrue(mDataLoaderType == DATA_LOADER_TYPE_NONE); 2577 2578 getUiAutomation().adoptShellPermissionIdentity( 2579 Manifest.permission.REQUEST_DELETE_PACKAGES, 2580 Manifest.permission.INSTALL_PACKAGES); 2581 2582 try { 2583 installPackage(TEST_INSTALLER_APP); 2584 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 2585 2586 final PackageInstaller installer = getPackageInstaller(); 2587 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2588 params.setAppPackageName(TEST_APP_PACKAGE); 2589 final int sessionId = installer.createSession(params); 2590 installer.openSession(sessionId); 2591 2592 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2593 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2594 2595 installer.uninstall(TEST_APP_PACKAGE, 2596 new IntentSender((IIntentSender) new IIntentSender.Stub() { 2597 @Override 2598 public void send(int code, Intent intent, String resolvedType, 2599 IBinder whitelistToken, IIntentReceiver finishedReceiver, 2600 String requiredPermission, Bundle options) throws RemoteException { 2601 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2602 Integer.MIN_VALUE)); 2603 statusMessage.complete( 2604 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 2605 } 2606 })); 2607 2608 assertEquals(statusMessage.get(), PackageInstaller.STATUS_PENDING_USER_ACTION, 2609 (int) status.get()); 2610 } finally { 2611 getUiAutomation().dropShellPermissionIdentity(); 2612 } 2613 } 2614 2615 // We can't test uninstalling a system app in CTS tests; this positive test will be in GTS tests 2616 // instead. 2617 @Test testEmergencyInstallerUninstallNonSystemApp()2618 public void testEmergencyInstallerUninstallNonSystemApp() throws Exception { 2619 assumeTrue(mDataLoaderType == DATA_LOADER_TYPE_NONE); 2620 getUiAutomation().adoptShellPermissionIdentity( 2621 Manifest.permission.EMERGENCY_INSTALL_PACKAGES, 2622 Manifest.permission.REQUEST_DELETE_PACKAGES, 2623 Manifest.permission.INSTALL_PACKAGES); 2624 2625 try { 2626 installPackage(TEST_INSTALLER_APP); 2627 assertTrue(isAppInstalled(TEST_APP_PACKAGE)); 2628 2629 final PackageInstaller installer = getPackageInstaller(); 2630 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 2631 params.setAppPackageName(TEST_APP_PACKAGE); 2632 final int sessionId = installer.createSession(params); 2633 installer.openSession(sessionId); 2634 2635 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2636 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2637 2638 installer.uninstall(TEST_APP_PACKAGE, 2639 new IntentSender((IIntentSender) new IIntentSender.Stub() { 2640 @Override 2641 public void send(int code, Intent intent, String resolvedType, 2642 IBinder whitelistToken, IIntentReceiver finishedReceiver, 2643 String requiredPermission, Bundle options) throws RemoteException { 2644 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2645 Integer.MIN_VALUE)); 2646 statusMessage.complete( 2647 intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); 2648 } 2649 })); 2650 2651 assertEquals(statusMessage.get(), PackageInstaller.STATUS_PENDING_USER_ACTION, 2652 (int) status.get()); 2653 } finally { 2654 getUiAutomation().dropShellPermissionIdentity(); 2655 } 2656 } 2657 getSharedLibraries()2658 private List<SharedLibraryInfo> getSharedLibraries() { 2659 getUiAutomation().adoptShellPermissionIdentity(); 2660 try { 2661 return getPackageManager().getSharedLibraries(PackageManager.PackageInfoFlags.of(0)); 2662 } finally { 2663 getUiAutomation().dropShellPermissionIdentity(); 2664 } 2665 } 2666 findLibrary(List<SharedLibraryInfo> libs, String name, long version)2667 private SharedLibraryInfo findLibrary(List<SharedLibraryInfo> libs, String name, long version) { 2668 for (int i = 0, size = libs.size(); i < size; ++i) { 2669 SharedLibraryInfo lib = libs.get(i); 2670 if (name.equals(lib.getName()) && version == lib.getLongVersion()) { 2671 return lib; 2672 } 2673 } 2674 return null; 2675 } 2676 createUpdateSession(String packageName)2677 private String createUpdateSession(String packageName) throws IOException { 2678 return createSession("-p " + packageName); 2679 } 2680 createSession(String arg)2681 private String createSession(String arg) throws IOException { 2682 final String prefix = "Success: created install session ["; 2683 final String suffix = "]\n"; 2684 final String commandResult = executeShellCommand("pm install-create " + arg); 2685 assertTrue(commandResult, commandResult.startsWith(prefix)); 2686 assertTrue(commandResult, commandResult.endsWith(suffix)); 2687 return commandResult.substring(prefix.length(), commandResult.length() - suffix.length()); 2688 } 2689 addSplits(String sessionId, String[] splitNames)2690 private void addSplits(String sessionId, String[] splitNames) throws IOException { 2691 for (String splitName : splitNames) { 2692 File file = new File(splitName); 2693 assertEquals( 2694 "Success: streamed " + file.length() + " bytes\n", 2695 executeShellCommand("pm install-write " + sessionId + " " + file.getName() + " " 2696 + splitName)); 2697 } 2698 } 2699 addSplitsStdIn(String sessionId, String[] splitNames, String args)2700 private void addSplitsStdIn(String sessionId, String[] splitNames, String args) 2701 throws IOException { 2702 for (String splitName : splitNames) { 2703 File file = new File(splitName); 2704 assertEquals("Success: streamed " + file.length() + " bytes\n", executeShellCommand( 2705 "pm install-write -S " + file.length() + " " + sessionId + " " + file.getName() 2706 + " " + args, file)); 2707 } 2708 } 2709 removeSplits(String sessionId, String[] splitNames)2710 private void removeSplits(String sessionId, String[] splitNames) throws IOException { 2711 for (String splitName : splitNames) { 2712 assertEquals("Success\n", 2713 executeShellCommand("pm install-remove " + sessionId + " " + splitName)); 2714 } 2715 } 2716 removeSplitsBatch(String sessionId, String[] splitNames)2717 private void removeSplitsBatch(String sessionId, String[] splitNames) throws IOException { 2718 assertEquals("Success\n", executeShellCommand( 2719 "pm install-remove " + sessionId + " " + String.join(" ", splitNames))); 2720 } 2721 commitSession(String sessionId)2722 private void commitSession(String sessionId) throws IOException { 2723 assertEquals("Success\n", executeShellCommand("pm install-commit " + sessionId)); 2724 } 2725 isAppInstalled(String packageName)2726 static boolean isAppInstalled(String packageName) throws IOException { 2727 final String commandResult = executeShellCommand("pm list packages"); 2728 final int prefixLength = "package:".length(); 2729 return Arrays.stream(commandResult.split("\\r?\\n")).anyMatch( 2730 line -> line.length() > prefixLength && line.substring(prefixLength).equals( 2731 packageName)); 2732 } 2733 isSdkInstalled(String name, int versionMajor)2734 private boolean isSdkInstalled(String name, int versionMajor) throws IOException { 2735 final String sdkString = name + ":" + versionMajor; 2736 final String commandResult = executeShellCommand("pm list sdks"); 2737 final int prefixLength = "sdk:".length(); 2738 return Arrays.stream(commandResult.split("\\r?\\n")) 2739 .anyMatch(line -> line.length() > prefixLength && line.substring( 2740 prefixLength).equals(sdkString)); 2741 } 2742 getPackageCertDigest(String packageName)2743 private String getPackageCertDigest(String packageName) throws Exception { 2744 getUiAutomation().adoptShellPermissionIdentity(); 2745 try { 2746 PackageInfo sdkPackageInfo = getPackageManager().getPackageInfo(packageName, 2747 PackageManager.PackageInfoFlags.of( 2748 GET_SIGNING_CERTIFICATES | MATCH_STATIC_SHARED_AND_SDK_LIBRARIES)); 2749 SigningInfo signingInfo = sdkPackageInfo.signingInfo; 2750 Signature[] signatures = 2751 signingInfo != null ? signingInfo.getSigningCertificateHistory() : null; 2752 byte[] digest = PackageUtils.computeSha256DigestBytes(signatures[0].toByteArray()); 2753 return new String(HexEncoding.encode(digest)); 2754 } finally { 2755 getUiAutomation().dropShellPermissionIdentity(); 2756 } 2757 } 2758 2759 /** 2760 * SDK package is signed by build system. In theory we could try to extract the signature, 2761 * and patch the app manifest. This property allows us to override in runtime, which is much 2762 * easier. 2763 */ overrideUsesSdkLibraryCertificateDigest(String sdkCertDigest)2764 private void overrideUsesSdkLibraryCertificateDigest(String sdkCertDigest) throws Exception { 2765 setSystemProperty("debug.pm.uses_sdk_library_default_cert_digest", sdkCertDigest); 2766 } 2767 getSplits(String packageName)2768 static String getSplits(String packageName) throws IOException { 2769 final String commandResult = executeShellCommand("pm dump " + packageName); 2770 final String prefix = " splits=["; 2771 final int prefixLength = prefix.length(); 2772 Optional<String> maybeSplits = Arrays.stream(commandResult.split("\\r?\\n")) 2773 .filter(line -> line.startsWith(prefix)).findFirst(); 2774 if (!maybeSplits.isPresent()) { 2775 return null; 2776 } 2777 String splits = maybeSplits.get(); 2778 return splits.substring(prefixLength, splits.length() - 1); 2779 } 2780 createApkPath(String baseName)2781 static String createApkPath(String baseName) { 2782 return TEST_APK_PATH + baseName; 2783 } 2784 2785 /* Install for all the users */ installPackage(String baseName)2786 private void installPackage(String baseName) throws IOException { 2787 File file = new File(createApkPath(baseName)); 2788 assertEquals("Success\n", executeShellCommand( 2789 "pm " + mInstall + " -t -g " + file.getPath())); 2790 } 2791 installPackage(String baseName, String expectedResultStartsWith)2792 private void installPackage(String baseName, String expectedResultStartsWith) 2793 throws IOException { 2794 File file = new File(createApkPath(baseName)); 2795 String result = executeShellCommand("pm " + mInstall + " -t -g " + file.getPath()); 2796 assertTrue(result, result.startsWith(expectedResultStartsWith)); 2797 } 2798 updatePackage(String packageName, String baseName)2799 private void updatePackage(String packageName, String baseName) throws IOException { 2800 File file = new File(createApkPath(baseName)); 2801 assertEquals("Success\n", executeShellCommand( 2802 "pm " + mInstall + " -t -p " + packageName + " -g " + file.getPath())); 2803 } 2804 updatePackageSkipEnable(String packageName, String baseName)2805 private void updatePackageSkipEnable(String packageName, String baseName) throws IOException { 2806 File file = new File(createApkPath(baseName)); 2807 assertEquals("Success\n", executeShellCommand( 2808 "pm " + mInstall + " --skip-enable -t -p " + packageName + " -g " + file.getPath() 2809 )); 2810 } 2811 installPackageStdIn(String baseName)2812 private void installPackageStdIn(String baseName) throws IOException { 2813 File file = new File(createApkPath(baseName)); 2814 assertEquals("Success\n", 2815 executeShellCommand("pm " + mInstall + " -t -g -S " + file.length(), file)); 2816 } 2817 updatePackageStdIn(String packageName, String baseName)2818 private void updatePackageStdIn(String packageName, String baseName) throws IOException { 2819 File file = new File(createApkPath(baseName)); 2820 assertEquals("Success\n", executeShellCommand( 2821 "pm " + mInstall + " -t -p " + packageName + " -g -S " + file.length(), file)); 2822 } 2823 installSplits(String[] baseNames)2824 private void installSplits(String[] baseNames) throws IOException { 2825 if (mStreaming) { 2826 installSplitsBatch(baseNames); 2827 return; 2828 } 2829 String[] splits = Arrays.stream(baseNames).map( 2830 baseName -> createApkPath(baseName)).toArray(String[]::new); 2831 String sessionId = createSession(TEST_APP_PACKAGE); 2832 addSplits(sessionId, splits); 2833 commitSession(sessionId); 2834 } 2835 updateSplits(String[] baseNames)2836 private void updateSplits(String[] baseNames) throws IOException { 2837 if (mStreaming) { 2838 updateSplitsBatch(baseNames); 2839 return; 2840 } 2841 String[] splits = Arrays.stream(baseNames).map( 2842 baseName -> createApkPath(baseName)).toArray(String[]::new); 2843 String sessionId = createSession("-p " + TEST_APP_PACKAGE); 2844 addSplits(sessionId, splits); 2845 commitSession(sessionId); 2846 } 2847 installSplitsStdInStreaming(String[] splits)2848 private void installSplitsStdInStreaming(String[] splits) throws IOException { 2849 File[] files = Arrays.stream(splits).map(split -> new File(split)).toArray(File[]::new); 2850 String param = Arrays.stream(files).map( 2851 file -> file.getName() + ":" + file.length()).collect(Collectors.joining(" ")); 2852 assertEquals("Success\n", executeShellCommand("pm" + mInstall + param, files)); 2853 } 2854 installSplitsStdIn(String[] baseNames, String args)2855 private void installSplitsStdIn(String[] baseNames, String args) throws IOException { 2856 String[] splits = Arrays.stream(baseNames).map( 2857 baseName -> createApkPath(baseName)).toArray(String[]::new); 2858 if (mStreaming) { 2859 installSplitsStdInStreaming(splits); 2860 return; 2861 } 2862 String sessionId = createSession(TEST_APP_PACKAGE); 2863 addSplitsStdIn(sessionId, splits, args); 2864 commitSession(sessionId); 2865 } 2866 installSplitsBatch(String[] baseNames)2867 private void installSplitsBatch(String[] baseNames) throws IOException { 2868 final String[] splits = Arrays.stream(baseNames).map( 2869 baseName -> createApkPath(baseName)).toArray(String[]::new); 2870 assertEquals("Success\n", 2871 executeShellCommand("pm " + mInstall + " -t -g " + String.join(" ", splits))); 2872 } 2873 updateSplitsBatch(String[] baseNames)2874 private void updateSplitsBatch(String[] baseNames) throws IOException { 2875 final String[] splits = Arrays.stream(baseNames).map( 2876 baseName -> createApkPath(baseName)).toArray(String[]::new); 2877 assertEquals("Success\n", executeShellCommand( 2878 "pm " + mInstall + " -p " + TEST_APP_PACKAGE + " -t -g " + String.join(" ", 2879 splits))); 2880 } 2881 uninstallPackage(String packageName, String expectedResultStartsWith)2882 private void uninstallPackage(String packageName, String expectedResultStartsWith) 2883 throws IOException { 2884 String result = uninstallPackageSilently(packageName); 2885 assertTrue(result, result.startsWith(expectedResultStartsWith)); 2886 } 2887 uninstallPackageSilently(String packageName)2888 private static String uninstallPackageSilently(String packageName) throws IOException { 2889 return executeShellCommand("pm uninstall " + packageName); 2890 } 2891 uninstallSplits(String packageName, String[] splitNames)2892 private void uninstallSplits(String packageName, String[] splitNames) throws IOException { 2893 for (String splitName : splitNames) { 2894 assertEquals("Success\n", 2895 executeShellCommand("pm uninstall " + packageName + " " + splitName)); 2896 } 2897 } 2898 uninstallSplitsBatch(String packageName, String[] splitNames)2899 private void uninstallSplitsBatch(String packageName, String[] splitNames) throws IOException { 2900 assertEquals("Success\n", executeShellCommand( 2901 "pm uninstall " + packageName + " " + String.join(" ", splitNames))); 2902 } 2903 setSystemProperty(String name, String value)2904 public static void setSystemProperty(String name, String value) throws Exception { 2905 assertEquals("", executeShellCommand("setprop " + name + " " + value)); 2906 } 2907 getSystemProperty(String prop)2908 public static String getSystemProperty(String prop) throws Exception { 2909 return executeShellCommand("getprop " + prop).replace("\n", ""); 2910 } 2911 disablePackage(String packageName)2912 private void disablePackage(String packageName) { 2913 getUiAutomation().adoptShellPermissionIdentity(); 2914 try { 2915 getPackageManager().setApplicationEnabledSetting(packageName, 2916 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); 2917 } finally { 2918 getUiAutomation().dropShellPermissionIdentity(); 2919 } 2920 } 2921 getOldCodePaths(String packageName)2922 private List<String> getOldCodePaths(String packageName) throws IOException { 2923 final String commandResult = executeShellCommand("dumpsys package " + packageName); 2924 final String prefix = " oldCodePath="; 2925 return Arrays.stream(commandResult.split("\\r?\\n")) 2926 .filter(line -> line.startsWith(prefix)) 2927 .map(s -> s.substring(prefix.length())) 2928 .toList(); 2929 } 2930 getFormattedBytes(long size)2931 private String getFormattedBytes(long size) { 2932 double k = size/1024.0; 2933 double m = size/1048576.0; 2934 double g = size/1073741824.0; 2935 2936 DecimalFormat dec = new DecimalFormat("0.00"); 2937 if (g > 1) { 2938 return dec.format(g).concat(" Gb"); 2939 } else if (m > 1) { 2940 return dec.format(m).concat(" Mb"); 2941 } else if (k > 1) { 2942 return dec.format(k).concat(" Kb"); 2943 } 2944 return ""; 2945 } 2946 2947 /** 2948 * Return the string that displays the data size. 2949 */ getDataSizeDisplay(long size)2950 private String getDataSizeDisplay(long size) { 2951 String formattedOutput = getFormattedBytes(size); 2952 if (!formattedOutput.isEmpty()) { 2953 formattedOutput = " (" + formattedOutput + ")"; 2954 } 2955 return Long.toString(size) + " bytes" + formattedOutput; 2956 } 2957 2958 static class PackageBroadcastReceiver extends BroadcastReceiver { 2959 private final String mTargetPackage; 2960 private final int mTargetUserId; 2961 private CompletableFuture<Intent> mUserReceivedBroadcast = new CompletableFuture(); 2962 private final String mAction; PackageBroadcastReceiver(String packageName, int targetUserId, String action)2963 PackageBroadcastReceiver(String packageName, int targetUserId, String action) { 2964 mTargetPackage = packageName; 2965 mTargetUserId = targetUserId; 2966 mAction = action; 2967 reset(); 2968 } 2969 @Override onReceive(Context context, Intent intent)2970 public void onReceive(Context context, Intent intent) { 2971 final String packageName = intent.getData() == null 2972 ? null : intent.getData().getEncodedSchemeSpecificPart(); 2973 final int userId = context.getUserId(); 2974 if (intent.getAction().equals(mAction) && userId == mTargetUserId 2975 && (packageName == null || packageName.equals(mTargetPackage))) { 2976 // Only check packageName if it is included in the intent 2977 mUserReceivedBroadcast.complete(intent); 2978 } 2979 } assertBroadcastReceived()2980 public void assertBroadcastReceived() throws Exception { 2981 // Make sure broadcast has been sent from PackageManager 2982 executeShellCommand("pm wait-for-handler --timeout 2000"); 2983 // Make sure broadcast has been dispatched from the queue 2984 executeShellCommand(String.format( 2985 "am wait-for-broadcast-dispatch -a %s -d package:%s", mAction, mTargetPackage)); 2986 // Checks that broadcast is delivered here 2987 assertNotNull(mUserReceivedBroadcast.get(6000, TimeUnit.MILLISECONDS)); 2988 } assertBroadcastNotReceived()2989 public void assertBroadcastNotReceived() throws Exception { 2990 // Make sure broadcast has been sent from PackageManager 2991 executeShellCommand("pm wait-for-handler --timeout 2000"); 2992 executeShellCommand(String.format( 2993 "am wait-for-broadcast-dispatch -a %s -d package:%s", mAction, mTargetPackage)); 2994 expectThrows(TimeoutException.class, 2995 () -> mUserReceivedBroadcast.get(500, TimeUnit.MILLISECONDS)); 2996 } 2997 getBroadcastResult()2998 public Intent getBroadcastResult() { 2999 return mUserReceivedBroadcast.getNow(null); 3000 } 3001 reset()3002 public void reset() { 3003 mUserReceivedBroadcast = new CompletableFuture(); 3004 } 3005 } 3006 } 3007 3008