1 /* 2 * Copyright (C) 2008 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.Manifest.permission.DELETE_PACKAGES; 20 import static android.Manifest.permission.INSTALL_PACKAGES; 21 import static android.Manifest.permission.INSTALL_TEST_ONLY_PACKAGE; 22 import static android.Manifest.permission.QUARANTINE_APPS; 23 import static android.Manifest.permission.WRITE_SECURE_SETTINGS; 24 import static android.content.Context.RECEIVER_EXPORTED; 25 import static android.content.Intent.FLAG_EXCLUDE_STOPPED_PACKAGES; 26 import static android.content.pm.ApplicationInfo.FLAG_HAS_CODE; 27 import static android.content.pm.ApplicationInfo.FLAG_INSTALLED; 28 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; 29 import static android.content.pm.Flags.FLAG_ARCHIVING; 30 import static android.content.pm.Flags.FLAG_GET_PACKAGE_INFO; 31 import static android.content.pm.Flags.FLAG_GET_PACKAGE_INFO_WITH_FD; 32 import static android.content.pm.Flags.FLAG_IMPROVE_HOME_APP_BEHAVIOR; 33 import static android.content.pm.Flags.FLAG_MIN_TARGET_SDK_24; 34 import static android.content.pm.Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX; 35 import static android.content.pm.Flags.FLAG_QUARANTINED_ENABLED; 36 import static android.content.pm.Flags.FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS; 37 import static android.content.pm.PackageInstaller.STATUS_FAILURE; 38 import static android.content.pm.PackageInstaller.STATUS_SUCCESS; 39 import static android.content.pm.PackageInstaller.SessionParams.MODE_FULL_INSTALL; 40 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 41 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 42 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 43 import static android.content.pm.PackageManager.DONT_KILL_APP; 44 import static android.content.pm.PackageManager.FLAG_SUSPEND_QUARANTINED; 45 import static android.content.pm.PackageManager.GET_ACTIVITIES; 46 import static android.content.pm.PackageManager.GET_INSTRUMENTATION; 47 import static android.content.pm.PackageManager.GET_META_DATA; 48 import static android.content.pm.PackageManager.GET_PERMISSIONS; 49 import static android.content.pm.PackageManager.GET_PROVIDERS; 50 import static android.content.pm.PackageManager.GET_RECEIVERS; 51 import static android.content.pm.PackageManager.GET_SERVICES; 52 import static android.content.pm.PackageManager.GET_SIGNATURES; 53 import static android.content.pm.PackageManager.MATCH_ANY_USER; 54 import static android.content.pm.PackageManager.MATCH_APEX; 55 import static android.content.pm.PackageManager.MATCH_ARCHIVED_PACKAGES; 56 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 57 import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; 58 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 59 import static android.content.pm.PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS; 60 import static android.content.pm.PackageManager.MATCH_INSTANT; 61 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES; 62 import static android.content.pm.PackageManager.MATCH_QUARANTINED_COMPONENTS; 63 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 64 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 65 import static android.content.pm.PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN; 66 import static android.content.pm.cts.PackageManagerShellCommandIncrementalTest.parsePackageDump; 67 import static android.os.UserHandle.CURRENT; 68 import static android.os.UserHandle.USER_CURRENT; 69 70 import static com.google.common.truth.Truth.assertThat; 71 import static com.google.common.truth.Truth.assertWithMessage; 72 73 import static org.junit.Assert.assertEquals; 74 import static org.junit.Assert.assertFalse; 75 import static org.junit.Assert.assertNotNull; 76 import static org.junit.Assert.assertNull; 77 import static org.junit.Assert.assertSame; 78 import static org.junit.Assert.assertTrue; 79 import static org.junit.Assert.fail; 80 import static org.junit.Assume.assumeTrue; 81 import static org.testng.Assert.assertThrows; 82 import static org.testng.Assert.expectThrows; 83 84 import android.Manifest; 85 import android.annotation.NonNull; 86 import android.app.Activity; 87 import android.app.ActivityManager; 88 import android.app.ActivityOptions; 89 import android.app.ActivityThread; 90 import android.app.Instrumentation; 91 import android.app.usage.StorageStats; 92 import android.app.usage.StorageStatsManager; 93 import android.content.BroadcastReceiver; 94 import android.content.ComponentName; 95 import android.content.Context; 96 import android.content.IIntentReceiver; 97 import android.content.IIntentSender; 98 import android.content.Intent; 99 import android.content.IntentFilter; 100 import android.content.IntentSender; 101 import android.content.ServiceConnection; 102 import android.content.cts.MockActivity; 103 import android.content.cts.MockContentProvider; 104 import android.content.cts.MockReceiver; 105 import android.content.cts.MockService; 106 import android.content.cts.R; 107 import android.content.pm.ActivityInfo; 108 import android.content.pm.ApplicationInfo; 109 import android.content.pm.ArchivedActivityInfo; 110 import android.content.pm.ArchivedPackageInfo; 111 import android.content.pm.ComponentInfo; 112 import android.content.pm.IPackageManager; 113 import android.content.pm.InstallSourceInfo; 114 import android.content.pm.InstrumentationInfo; 115 import android.content.pm.PackageInfo; 116 import android.content.pm.PackageInstaller; 117 import android.content.pm.PackageInstaller.SessionParams; 118 import android.content.pm.PackageItemInfo; 119 import android.content.pm.PackageManager; 120 import android.content.pm.PackageManager.ComponentEnabledSetting; 121 import android.content.pm.PackageManager.NameNotFoundException; 122 import android.content.pm.PermissionGroupInfo; 123 import android.content.pm.PermissionInfo; 124 import android.content.pm.ProviderInfo; 125 import android.content.pm.ResolveInfo; 126 import android.content.pm.ServiceInfo; 127 import android.content.pm.SharedLibraryInfo; 128 import android.content.pm.Signature; 129 import android.content.pm.SigningInfo; 130 import android.content.pm.SuspendDialogInfo; 131 import android.content.pm.cts.PackageManagerShellCommandInstallTest.PackageBroadcastReceiver; 132 import android.content.pm.cts.util.AbandonAllPackageSessionsRule; 133 import android.content.res.Configuration; 134 import android.content.res.Resources; 135 import android.content.res.TypedArray; 136 import android.content.res.XmlResourceParser; 137 import android.graphics.drawable.BitmapDrawable; 138 import android.os.Build; 139 import android.os.Bundle; 140 import android.os.Environment; 141 import android.os.IBinder; 142 import android.os.ParcelFileDescriptor; 143 import android.os.Process; 144 import android.os.RemoteException; 145 import android.os.SystemClock; 146 import android.os.UserHandle; 147 import android.platform.test.annotations.AppModeFull; 148 import android.platform.test.annotations.RequiresFlagsDisabled; 149 import android.platform.test.annotations.RequiresFlagsEnabled; 150 import android.platform.test.flag.junit.CheckFlagsRule; 151 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 152 import android.provider.Settings; 153 import android.text.TextUtils; 154 import android.util.Log; 155 156 import androidx.test.ext.junit.runners.AndroidJUnit4; 157 import androidx.test.filters.SdkSuppress; 158 import androidx.test.platform.app.InstrumentationRegistry; 159 import androidx.test.rule.ServiceTestRule; 160 import androidx.test.uiautomator.UiDevice; 161 162 import com.android.compatibility.common.util.CddTest; 163 import com.android.compatibility.common.util.FileUtils; 164 import com.android.compatibility.common.util.PollingCheck; 165 import com.android.compatibility.common.util.SystemUtil; 166 import com.android.compatibility.common.util.TestUtils; 167 import com.android.internal.security.VerityUtils; 168 169 import com.google.common.truth.Expect; 170 171 import junit.framework.AssertionFailedError; 172 173 import org.junit.After; 174 import org.junit.Before; 175 import org.junit.Rule; 176 import org.junit.Test; 177 import org.junit.runner.RunWith; 178 import org.xmlpull.v1.XmlPullParser; 179 import org.xmlpull.v1.XmlPullParserException; 180 181 import java.io.BufferedReader; 182 import java.io.File; 183 import java.io.FileInputStream; 184 import java.io.FileOutputStream; 185 import java.io.IOException; 186 import java.io.InputStream; 187 import java.io.InputStreamReader; 188 import java.security.PublicKey; 189 import java.security.cert.Certificate; 190 import java.security.cert.CertificateFactory; 191 import java.util.ArrayList; 192 import java.util.Arrays; 193 import java.util.Collections; 194 import java.util.HashSet; 195 import java.util.Iterator; 196 import java.util.List; 197 import java.util.Set; 198 import java.util.concurrent.CompletableFuture; 199 import java.util.concurrent.CountDownLatch; 200 import java.util.concurrent.TimeUnit; 201 import java.util.concurrent.TimeoutException; 202 import java.util.concurrent.atomic.AtomicBoolean; 203 import java.util.function.Consumer; 204 import java.util.stream.Collectors; 205 206 /** 207 * This test is based on the declarations in AndroidManifest.xml. We create mock declarations 208 * in AndroidManifest.xml just for test of PackageManager, and there are no corresponding parts 209 * of these declarations in test project. 210 */ 211 @AppModeFull // TODO(Instant) Figure out which APIs should work. 212 @RunWith(AndroidJUnit4.class) 213 public class PackageManagerTest { 214 private static final String TAG = "PackageManagerTest"; 215 216 private Context mContext; 217 private PackageManager mPackageManager; 218 private Instrumentation mInstrumentation; 219 private static final String PACKAGE_NAME = "android.content.cts"; 220 private static final String STUB_PACKAGE_NAME = "com.android.cts.stub"; 221 private static final String APPLICATION_NAME = "android.content.cts.MockApplication"; 222 private static final String ACTIVITY_ACTION_NAME = "android.intent.action.PMTEST"; 223 private static final String MAIN_ACTION_NAME = "android.intent.action.MAIN"; 224 private static final String SERVICE_ACTION_NAME = 225 "android.content.pm.cts.activity.PMTEST_SERVICE"; 226 private static final String RECEIVER_ACTION_NAME = 227 "android.content.pm.cts.PackageManagerTest.PMTEST_RECEIVER"; 228 private static final String GRANTED_PERMISSION_NAME = "android.permission.INTERNET"; 229 private static final String NOT_GRANTED_PERMISSION_NAME = "android.permission.HARDWARE_TEST"; 230 private static final String ACTIVITY_NAME = "android.content.pm.cts.TestPmActivity"; 231 private static final String SERVICE_NAME = "android.content.pm.cts.TestPmService"; 232 private static final String RECEIVER_NAME = "android.content.pm.cts.PmTestReceiver"; 233 private static final String INSTRUMENT_NAME = "android.content.pm.cts.TestPmInstrumentation"; 234 private static final String CALL_ABROAD_PERMISSION_NAME = 235 "android.content.cts.CALL_ABROAD_PERMISSION"; 236 private static final String PROVIDER_NAME = "android.content.cts.MockContentProvider"; 237 private static final String PERMISSIONGROUP_NAME = "android.permission-group.COST_MONEY"; 238 private static final String PERMISSION_TREE_ROOT = 239 "android.content.cts.permission.TEST_DYNAMIC"; 240 // Number of activities/activity-alias in AndroidManifest 241 private static final int NUM_OF_ACTIVITIES_IN_MANIFEST = 23; 242 public static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); 243 244 private static final String SHIM_APEX_PACKAGE_NAME = "com.android.apex.cts.shim"; 245 246 private static final int[] PACKAGE_INFO_MATCH_FLAGS = {MATCH_UNINSTALLED_PACKAGES, 247 MATCH_DISABLED_COMPONENTS, MATCH_SYSTEM_ONLY, MATCH_FACTORY_ONLY, MATCH_INSTANT, 248 MATCH_APEX, MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS}; 249 250 private static final String SAMPLE_APK_BASE = "/data/local/tmp/cts/content/"; 251 private static final String EMPTY_APP_APK = SAMPLE_APK_BASE 252 + "CtsContentEmptyTestApp.apk"; 253 private static final String LONG_PACKAGE_NAME_APK = SAMPLE_APK_BASE 254 + "CtsContentLongPackageNameTestApp.apk"; 255 private static final String LONG_SHARED_USER_ID_APK = SAMPLE_APK_BASE 256 + "CtsContentLongSharedUserIdTestApp.apk"; 257 private static final String MAX_PACKAGE_NAME_APK = SAMPLE_APK_BASE 258 + "CtsContentMaxPackageNameTestApp.apk"; 259 private static final String MAX_SHARED_USER_ID_APK = SAMPLE_APK_BASE 260 + "CtsContentMaxSharedUserIdTestApp.apk"; 261 private static final String LONG_LABEL_NAME_APK = SAMPLE_APK_BASE 262 + "CtsContentLongLabelNameTestApp.apk"; 263 private static final String LONG_USES_PERMISSION_NAME_APK = SAMPLE_APK_BASE 264 + "CtsContentLongUsesPermissionNameTestApp.apk"; 265 private static final String SHELL_NAME_APK = SAMPLE_APK_BASE 266 + "CtsContentShellTestApp.apk"; 267 private static final String CTS_TARGET_SDK_23 = SAMPLE_APK_BASE + "CtsTargetSdk23TestApp.apk"; 268 private static final String CTS_TARGET_SDK_24 = SAMPLE_APK_BASE + "CtsTargetSdk24TestApp.apk"; 269 270 private static final String TEST_ICON = SAMPLE_APK_BASE + "icon.png"; 271 private static final String TEST_ICON_MONO = SAMPLE_APK_BASE + "icon_mono.png"; 272 private static final String DIFF_SIGNER_CERTIFICATE = SAMPLE_APK_BASE + "cts-testkey1.x509.pem"; 273 274 private static final String EMPTY_APP_PACKAGE_NAME = "android.content.cts.emptytestapp"; 275 private static final String EMPTY_APP_ACTIVITY_NAME = 276 "android.content.cts.emptytestapp.MockActivity"; 277 private static final String EMPTY_APP_MAX_PACKAGE_NAME = "android.content.cts.emptytestapp27j" 278 + "EBRNRG3ozwBsGr1sVIM9U0bVTI2TdyIyeRkZgW4JrJefwNIBAmCg4AzqXiCvG6JjqA0uTCWSFu2YqAVxVd" 279 + "iRKAay19k5VFlSaM7QW9uhvlrLQqsTW01ofFzxNDbp2QfIFHZR6rebKzKBz6byQFM0DYQnYMwFWXjWkMPN" 280 + "dqkRLykoFLyBup53G68k2n8w"; 281 private static final String EMPTY_APP_LONG_USES_PERMISSION_PACKAGE_NAME = 282 EMPTY_APP_PACKAGE_NAME + ".longusespermission"; 283 private static final String SETTINGS_PROVIDER_PACKAGE_NAME = "com.android.providers.settings"; 284 private static final String SHELL_PACKAGE_NAME = "com.android.shell"; 285 private static final String CTS_TARGET_SDK_23_PACKAGE_NAME = 286 "android.content.cts.emptytestapp.sdk23"; 287 private static final String CTS_TARGET_SDK_24_PACKAGE_NAME = 288 "android.content.cts.emptytestapp.sdk24"; 289 private static final String HELLO_WORLD_PACKAGE_NAME = "com.example.helloworld"; 290 private static final String HELLO_WORLD_APK = SAMPLE_APK_BASE + "HelloWorld5.apk"; 291 private static final String HELLO_WORLD_DIFF_SIGNER_APK = 292 SAMPLE_APK_BASE + "HelloWorld5DifferentSigner.apk"; 293 private static final String HELLO_WORLD_FLAGS_APK = 294 SAMPLE_APK_BASE + "HelloWorld5NonDefaultFlags.apk"; 295 private static final String HELLO_WORLD_UPDATED_APK = SAMPLE_APK_BASE + "HelloWorld7.apk"; 296 private static final String HELLO_WORLD_LOTS_OF_FLAGS_APK = 297 SAMPLE_APK_BASE + "HelloWorldLotsOfFlags.apk"; 298 private static final String HELLO_WORLD_NON_UPDATABLE_SYSTEM_APK = SAMPLE_APK_BASE 299 + "HelloWorldNonUpdatableSystem.apk"; 300 301 private static final String HELLO_WORLD_SHARED_UID_APK = SAMPLE_APK_BASE 302 + "HelloWorldSharedUid.apk"; 303 304 private static final String HELLO_WORLD_SETTINGS = SAMPLE_APK_BASE 305 + "HelloWorldSettings.apk"; 306 307 private static final String HELLO_WORLD_SETTINGS2 = SAMPLE_APK_BASE 308 + "HelloWorldSettings2.apk"; 309 310 private static final String HELLO_WORLD_SETTINGS_PACKAGE_NAME = "android.test.settings"; 311 312 private static final String HELLO_WORLD_SETTINGS2_PACKAGE_NAME = "android.test.settings2"; 313 314 private static final String MOCK_LAUNCHER_PACKAGE_NAME = "android.content.cts.mocklauncherapp"; 315 private static final String MOCK_LAUNCHER_APK = SAMPLE_APK_BASE 316 + "CtsContentMockLauncherTestApp.apk"; 317 private static final String NON_EXISTENT_PACKAGE_NAME = "android.content.cts.nonexistent.pkg"; 318 private static final String STUB_PACKAGE_APK = SAMPLE_APK_BASE 319 + "CtsSyncAccountAccessStubs.apk"; 320 private static final String STUB_PACKAGE_SPLIT = 321 SAMPLE_APK_BASE + "CtsSyncAccountAccessStubs_mdpi-v4.apk"; 322 private static final String TEST_HW_NO_APP_STORAGE = 323 SAMPLE_APK_BASE + "HelloWorldNoAppStorage.apk"; 324 325 private static final int MAX_SAFE_LABEL_LENGTH = 1000; 326 327 // For intent resolution tests 328 private static final String TAG_MANIFEST = "manifest"; 329 private static final String MIME_GROUP = "mime_group"; 330 331 private static final ComponentName ACTIVITY_COMPONENT = new ComponentName( 332 PACKAGE_NAME, ACTIVITY_NAME); 333 private static final ComponentName SERVICE_COMPONENT = new ComponentName( 334 PACKAGE_NAME, SERVICE_NAME); 335 private static final ComponentName STUB_ACTIVITY_COMPONENT = ComponentName.createRelative( 336 STUB_PACKAGE_NAME, ".StubActivity"); 337 private static final ComponentName STUB_SERVICE_COMPONENT = ComponentName.createRelative( 338 STUB_PACKAGE_NAME, ".StubService"); 339 private static final ComponentName RESET_ENABLED_SETTING_ACTIVITY_COMPONENT = 340 ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockActivity"); 341 private static final ComponentName RESET_ENABLED_SETTING_RECEIVER_COMPONENT = 342 ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockReceiver"); 343 private static final ComponentName RESET_ENABLED_SETTING_SERVICE_COMPONENT = 344 ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockService"); 345 private static final ComponentName RESET_ENABLED_SETTING_PROVIDER_COMPONENT = 346 ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockProvider"); 347 static final String CTS_SHIM_PACKAGE_NAME = "com.android.cts.ctsshim"; 348 349 private final ServiceTestRule mServiceTestRule = new ServiceTestRule(); 350 351 @Rule 352 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 353 @Rule 354 public AbandonAllPackageSessionsRule mAbandonSessionsRule = new AbandonAllPackageSessionsRule(); 355 356 @Rule 357 public final Expect expect = Expect.create(); 358 359 private UiDevice mUiDevice; 360 361 @Before setup()362 public void setup() throws Exception { 363 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 364 mContext = mInstrumentation.getContext(); 365 mPackageManager = mContext.getPackageManager(); 366 mUiDevice = UiDevice.getInstance(mInstrumentation); 367 } 368 369 @After tearDown()370 public void tearDown() throws Exception { 371 uninstallPackage(EMPTY_APP_PACKAGE_NAME); 372 uninstallPackage(EMPTY_APP_MAX_PACKAGE_NAME); 373 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 374 uninstallPackage(MOCK_LAUNCHER_PACKAGE_NAME); 375 uninstallPackage(EMPTY_APP_LONG_USES_PERMISSION_PACKAGE_NAME); 376 uninstallPackage(CTS_TARGET_SDK_23_PACKAGE_NAME); 377 uninstallPackage(CTS_TARGET_SDK_24_PACKAGE_NAME); 378 } 379 380 @Test testQuery()381 public void testQuery() throws NameNotFoundException { 382 // Test query Intent Activity related methods 383 384 Intent activityIntent = new Intent(ACTIVITY_ACTION_NAME); 385 String cmpActivityName = "android.content.pm.cts.TestPmCompare"; 386 // List with different activities and the filter doesn't work, 387 List<ResolveInfo> listWithDiff = mPackageManager.queryIntentActivityOptions( 388 new ComponentName(PACKAGE_NAME, cmpActivityName), null, activityIntent, 389 PackageManager.ResolveInfoFlags.of(0)); 390 checkActivityInfoName(ACTIVITY_NAME, listWithDiff); 391 392 // List with the same activities to make filter work 393 List<ResolveInfo> listInSame = mPackageManager.queryIntentActivityOptions( 394 new ComponentName(PACKAGE_NAME, ACTIVITY_NAME), null, activityIntent, 395 PackageManager.ResolveInfoFlags.of(0)); 396 assertEquals(0, listInSame.size()); 397 398 // Test queryIntentActivities 399 List<ResolveInfo> intentActivities = 400 mPackageManager.queryIntentActivities(activityIntent, 401 PackageManager.ResolveInfoFlags.of(0)); 402 assertTrue(intentActivities.size() > 0); 403 checkActivityInfoName(ACTIVITY_NAME, intentActivities); 404 405 // End of Test query Intent Activity related methods 406 407 // Test queryInstrumentation 408 String targetPackage = "android"; 409 List<InstrumentationInfo> instrumentations = mPackageManager.queryInstrumentation( 410 targetPackage, 0); 411 checkInstrumentationInfoName(INSTRUMENT_NAME, instrumentations); 412 413 // Test queryIntentServices 414 Intent serviceIntent = new Intent(SERVICE_ACTION_NAME); 415 List<ResolveInfo> services = mPackageManager.queryIntentServices(serviceIntent, 416 PackageManager.ResolveInfoFlags.of(0)); 417 checkServiceInfoName(SERVICE_NAME, services); 418 419 // Test queryBroadcastReceivers 420 Intent broadcastIntent = new Intent(RECEIVER_ACTION_NAME); 421 List<ResolveInfo> broadcastReceivers = 422 mPackageManager.queryBroadcastReceivers(broadcastIntent, 423 PackageManager.ResolveInfoFlags.of(0)); 424 checkActivityInfoName(RECEIVER_NAME, broadcastReceivers); 425 426 // Test queryPermissionsByGroup, queryContentProviders 427 String testPermissionsGroup = "android.permission-group.COST_MONEY"; 428 List<PermissionInfo> permissions = mPackageManager.queryPermissionsByGroup( 429 testPermissionsGroup, PackageManager.GET_META_DATA); 430 checkPermissionInfoName(CALL_ABROAD_PERMISSION_NAME, permissions); 431 432 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 433 PackageManager.ApplicationInfoFlags.of(0)); 434 List<ProviderInfo> providers = mPackageManager.queryContentProviders(PACKAGE_NAME, 435 appInfo.uid, PackageManager.ComponentInfoFlags.of(0)); 436 checkProviderInfoName(PROVIDER_NAME, providers); 437 } 438 439 @Test testStoppedPackagesQuery()440 public void testStoppedPackagesQuery() throws NameNotFoundException { 441 installPackage(HELLO_WORLD_APK); 442 443 final Intent intent = new Intent(ACTIVITY_ACTION_NAME); 444 intent.addFlags(FLAG_EXCLUDE_STOPPED_PACKAGES); 445 446 // Stopped after install. 447 { 448 final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent, 449 PackageManager.ResolveInfoFlags.of(0)); 450 assertFalse(containsActivityInfoName("com.example.helloworld.MainActivity", matches)); 451 } 452 453 launchMainActivity(HELLO_WORLD_PACKAGE_NAME); 454 455 // Started. 456 { 457 final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent, 458 PackageManager.ResolveInfoFlags.of(0)); 459 assertTrue(containsActivityInfoName("com.example.helloworld.MainActivity", matches)); 460 } 461 462 assertEquals("", SystemUtil.runShellCommand("am force-stop " + HELLO_WORLD_PACKAGE_NAME)); 463 464 // Force stopped. 465 { 466 final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent, 467 PackageManager.ResolveInfoFlags.of(0)); 468 assertFalse(containsActivityInfoName("com.example.helloworld.MainActivity", matches)); 469 } 470 } 471 launchMainActivity(String packageName)472 public static void launchMainActivity(String packageName) { 473 SystemUtil.runShellCommand("am start -W " 474 + "--user current " 475 + "-a android.intent.action.MAIN " 476 + "-c android.intent.category.LAUNCHER " 477 + packageName + "/.MainActivity"); 478 } 479 containsActivityInfoName(String expectedName, List<ResolveInfo> resolves)480 private boolean containsActivityInfoName(String expectedName, List<ResolveInfo> resolves) { 481 Iterator<ResolveInfo> infoIterator = resolves.iterator(); 482 String current; 483 while (infoIterator.hasNext()) { 484 current = infoIterator.next().activityInfo.name; 485 if (current.equals(expectedName)) { 486 return true; 487 } 488 } 489 return false; 490 } 491 checkActivityInfoName(String expectedName, List<ResolveInfo> resolves)492 private void checkActivityInfoName(String expectedName, List<ResolveInfo> resolves) { 493 assertTrue(containsActivityInfoName(expectedName, resolves)); 494 } 495 checkServiceInfoName(String expectedName, List<ResolveInfo> resolves)496 private void checkServiceInfoName(String expectedName, List<ResolveInfo> resolves) { 497 boolean isContained = false; 498 Iterator<ResolveInfo> infoIterator = resolves.iterator(); 499 String current; 500 while (infoIterator.hasNext()) { 501 current = infoIterator.next().serviceInfo.name; 502 if (current.equals(expectedName)) { 503 isContained = true; 504 break; 505 } 506 } 507 assertTrue(isContained); 508 } 509 checkPermissionInfoName(String expectedName, List<PermissionInfo> permissions)510 private void checkPermissionInfoName(String expectedName, List<PermissionInfo> permissions) { 511 List<String> names = new ArrayList<String>(); 512 for (PermissionInfo permission : permissions) { 513 names.add(permission.name); 514 } 515 boolean isContained = names.contains(expectedName); 516 assertTrue("Permission " + expectedName + " not present in " + names, isContained); 517 } 518 checkProviderInfoName(String expectedName, List<ProviderInfo> providers)519 private void checkProviderInfoName(String expectedName, List<ProviderInfo> providers) { 520 boolean isContained = false; 521 Iterator<ProviderInfo> infoIterator = providers.iterator(); 522 String current; 523 while (infoIterator.hasNext()) { 524 current = infoIterator.next().name; 525 if (current.equals(expectedName)) { 526 isContained = true; 527 break; 528 } 529 } 530 assertTrue(isContained); 531 } 532 checkInstrumentationInfoName(String expectedName, List<InstrumentationInfo> instrumentations)533 private void checkInstrumentationInfoName(String expectedName, 534 List<InstrumentationInfo> instrumentations) { 535 boolean isContained = false; 536 Iterator<InstrumentationInfo> infoIterator = instrumentations.iterator(); 537 String current; 538 while (infoIterator.hasNext()) { 539 current = infoIterator.next().name; 540 if (current.equals(expectedName)) { 541 isContained = true; 542 break; 543 } 544 } 545 assertTrue(isContained); 546 } 547 548 @Test testGetInfo()549 public void testGetInfo() throws NameNotFoundException { 550 // Test getApplicationInfo, getText 551 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 552 PackageManager.ApplicationInfoFlags.of(0)); 553 int discriptionRes = R.string.hello_android; 554 String expectedDisciptionRes = "Hello, Android!"; 555 CharSequence appText = mPackageManager.getText(PACKAGE_NAME, discriptionRes, appInfo); 556 assertEquals(expectedDisciptionRes, appText); 557 ComponentName activityName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME); 558 ComponentName serviceName = new ComponentName(PACKAGE_NAME, SERVICE_NAME); 559 ComponentName receiverName = new ComponentName(PACKAGE_NAME, RECEIVER_NAME); 560 ComponentName instrName = new ComponentName(PACKAGE_NAME, INSTRUMENT_NAME); 561 562 // Test getPackageInfo 563 PackageInfo packageInfo = mPackageManager.getPackageInfo(PACKAGE_NAME, 564 PackageManager.PackageInfoFlags.of(GET_INSTRUMENTATION)); 565 assertEquals(PACKAGE_NAME, packageInfo.packageName); 566 567 // Test getApplicationInfo, getApplicationLabel 568 String appLabel = "Android TestCase"; 569 assertEquals(appLabel, mPackageManager.getApplicationLabel(appInfo)); 570 assertEquals(PACKAGE_NAME, appInfo.processName); 571 572 // Test getServiceInfo 573 assertEquals(SERVICE_NAME, mPackageManager.getServiceInfo(serviceName, 574 PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)).name); 575 576 // Test getReceiverInfo 577 assertEquals(RECEIVER_NAME, mPackageManager.getReceiverInfo(receiverName, 578 PackageManager.ComponentInfoFlags.of(0)).name); 579 580 // Test getPackageArchiveInfo 581 final String apkRoute = mContext.getPackageCodePath(); 582 final String apkName = mContext.getPackageName(); 583 assertEquals(apkName, mPackageManager.getPackageArchiveInfo(apkRoute, 584 PackageManager.PackageInfoFlags.of(0)).packageName); 585 586 // Test getPackagesForUid, getNameForUid 587 checkPackagesNameForUid(PACKAGE_NAME, mPackageManager.getPackagesForUid(appInfo.uid)); 588 assertEquals(PACKAGE_NAME, mPackageManager.getNameForUid(appInfo.uid)); 589 590 // Test getActivityInfo 591 assertEquals(ACTIVITY_NAME, mPackageManager.getActivityInfo(activityName, 592 PackageManager.ComponentInfoFlags.of(0)).name); 593 594 // Test getPackageGids 595 assertTrue(mPackageManager.getPackageGids(PACKAGE_NAME).length > 0); 596 597 // Test getPermissionInfo 598 assertEquals(GRANTED_PERMISSION_NAME, 599 mPackageManager.getPermissionInfo(GRANTED_PERMISSION_NAME, 0).name); 600 601 // Test getPermissionGroupInfo 602 assertEquals(PERMISSIONGROUP_NAME, mPackageManager.getPermissionGroupInfo( 603 PERMISSIONGROUP_NAME, 0).name); 604 605 // Test getAllPermissionGroups 606 List<PermissionGroupInfo> permissionGroups = mPackageManager.getAllPermissionGroups(0); 607 checkPermissionGroupInfoName(PERMISSIONGROUP_NAME, permissionGroups); 608 609 // Test getInstalledApplications 610 assertTrue(mPackageManager.getInstalledApplications( 611 PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA)).size() > 0); 612 613 // Test getInstalledPacakge 614 assertTrue(mPackageManager.getInstalledPackages( 615 PackageManager.PackageInfoFlags.of(0)).size() > 0); 616 617 // Test getInstrumentationInfo 618 assertEquals(INSTRUMENT_NAME, mPackageManager.getInstrumentationInfo(instrName, 0).name); 619 620 // Test getSystemSharedLibraryNames, in javadoc, String array and null 621 // are all OK as return value. 622 mPackageManager.getSystemSharedLibraryNames(); 623 624 // Test getLaunchIntentForPackage, Intent of activity 625 // android.content.pm.cts.TestPmCompare is set to match the condition 626 // to make sure the return of this method is not null. 627 assertEquals(MAIN_ACTION_NAME, mPackageManager.getLaunchIntentForPackage(PACKAGE_NAME) 628 .getAction()); 629 630 // Test isSafeMode. Because the test case will not run in safe mode, so 631 // the return will be false. 632 assertFalse(mPackageManager.isSafeMode()); 633 634 // Test getTargetSdkVersion 635 int expectedTargetSdk = mPackageManager.getApplicationInfo(PACKAGE_NAME, 636 PackageManager.ApplicationInfoFlags.of(0)).targetSdkVersion; 637 assertEquals(expectedTargetSdk, mPackageManager.getTargetSdkVersion(PACKAGE_NAME)); 638 assertThrows(PackageManager.NameNotFoundException.class, 639 () -> mPackageManager.getTargetSdkVersion( 640 "android.content.cts.non_existent_package")); 641 } 642 checkPackagesNameForUid(String expectedName, String[] uid)643 private void checkPackagesNameForUid(String expectedName, String[] uid) { 644 boolean isContained = false; 645 for (int i = 0; i < uid.length; i++) { 646 if (uid[i].equals(expectedName)) { 647 isContained = true; 648 break; 649 } 650 } 651 assertTrue(isContained); 652 } 653 checkPermissionGroupInfoName(String expectedName, List<PermissionGroupInfo> permissionGroups)654 private void checkPermissionGroupInfoName(String expectedName, 655 List<PermissionGroupInfo> permissionGroups) { 656 boolean isContained = false; 657 Iterator<PermissionGroupInfo> infoIterator = permissionGroups.iterator(); 658 String current; 659 while (infoIterator.hasNext()) { 660 current = infoIterator.next().name; 661 if (current.equals(expectedName)) { 662 isContained = true; 663 break; 664 } 665 } 666 assertTrue(isContained); 667 } 668 669 670 /** 671 * Simple test for {@link PackageManager#getPreferredActivities(List, List, String)} that tests 672 * calling it has no effect. The method is essentially a no-op because no preferred activities 673 * can be added. 674 * 675 * @see PackageManager#addPreferredActivity(IntentFilter, int, ComponentName[], ComponentName) 676 */ 677 @Test testGetPreferredActivities()678 public void testGetPreferredActivities() { 679 assertNoPreferredActivities(); 680 } 681 682 /** 683 * Helper method to test that {@link PackageManager#getPreferredActivities(List, List, String)} 684 * returns empty lists. 685 */ assertNoPreferredActivities()686 private void assertNoPreferredActivities() { 687 List<ComponentName> outActivities = new ArrayList<ComponentName>(); 688 List<IntentFilter> outFilters = new ArrayList<IntentFilter>(); 689 mPackageManager.getPreferredActivities(outFilters, outActivities, PACKAGE_NAME); 690 assertEquals(0, outActivities.size()); 691 assertEquals(0, outFilters.size()); 692 } 693 694 /** 695 * Test that calling {@link PackageManager#addPreferredActivity(IntentFilter, int, 696 * ComponentName[], ComponentName)} throws a {@link SecurityException}. 697 * <p/> 698 * The method is protected by the {@link android.permission.SET_PREFERRED_APPLICATIONS} 699 * signature permission. Even though this app declares that permission, it still should not be 700 * able to call this method because it is not signed with the platform certificate. 701 */ 702 @Test testAddPreferredActivity()703 public void testAddPreferredActivity() { 704 IntentFilter intentFilter = new IntentFilter(ACTIVITY_ACTION_NAME); 705 ComponentName[] componentName = {new ComponentName(PACKAGE_NAME, ACTIVITY_NAME)}; 706 try { 707 mPackageManager.addPreferredActivity(intentFilter, IntentFilter.MATCH_CATEGORY_HOST, 708 componentName, componentName[0]); 709 fail("addPreferredActivity unexpectedly succeeded"); 710 } catch (SecurityException e) { 711 // expected 712 } 713 assertNoPreferredActivities(); 714 } 715 716 /** 717 * Test that calling {@link PackageManager#clearPackagePreferredActivities(String)} has no 718 * effect. 719 */ 720 @Test testClearPackagePreferredActivities()721 public void testClearPackagePreferredActivities() { 722 // just ensure no unexpected exceptions are thrown, nothing else to do 723 mPackageManager.clearPackagePreferredActivities(PACKAGE_NAME); 724 } 725 726 @Test testEnabledSettingAfterUpdate()727 public void testEnabledSettingAfterUpdate() { 728 assertThat(installPackage(LONG_LABEL_NAME_APK)).isTrue(); 729 730 ComponentName compName = new ComponentName(EMPTY_APP_PACKAGE_NAME, EMPTY_APP_ACTIVITY_NAME); 731 SystemUtil.runWithShellPermissionIdentity(() -> 732 mPackageManager.setComponentEnabledSetting(compName, 733 COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP)); 734 assertEquals(COMPONENT_ENABLED_STATE_ENABLED, 735 mPackageManager.getComponentEnabledSetting(compName)); 736 737 // Update to the app whose enabled component is removed 738 assertThat(installPackage(EMPTY_APP_APK)).isTrue(); 739 assertEquals(COMPONENT_ENABLED_STATE_DEFAULT, 740 mPackageManager.getComponentEnabledSetting(compName)); 741 } 742 743 @Test testAccessEnabledSetting()744 public void testAccessEnabledSetting() { 745 mPackageManager.setApplicationEnabledSetting(PACKAGE_NAME, 746 COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); 747 assertEquals(COMPONENT_ENABLED_STATE_ENABLED, 748 mPackageManager.getApplicationEnabledSetting(PACKAGE_NAME)); 749 750 ComponentName componentName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME); 751 mPackageManager.setComponentEnabledSetting(componentName, 752 COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); 753 assertEquals(COMPONENT_ENABLED_STATE_ENABLED, 754 mPackageManager.getComponentEnabledSetting(componentName)); 755 } 756 757 @Test testGetApplicationEnabledSetting_notFound()758 public void testGetApplicationEnabledSetting_notFound() { 759 try { 760 mPackageManager.getApplicationEnabledSetting("this.package.does.not.exist"); 761 fail("Exception expected"); 762 } catch (IllegalArgumentException expected) { 763 } 764 } 765 766 @Test testGetIcon()767 public void testGetIcon() throws NameNotFoundException { 768 assertNotNull(mPackageManager.getApplicationIcon(PACKAGE_NAME)); 769 assertNotNull(mPackageManager.getApplicationIcon(mPackageManager.getApplicationInfo( 770 PACKAGE_NAME, 0))); 771 assertNotNull(mPackageManager 772 .getActivityIcon(new ComponentName(PACKAGE_NAME, ACTIVITY_NAME))); 773 assertNotNull(mPackageManager.getActivityIcon(new Intent(MAIN_ACTION_NAME))); 774 775 assertNotNull(mPackageManager.getDefaultActivityIcon()); 776 assertTrue(mPackageManager.isDefaultApplicationIcon( 777 mPackageManager.getDefaultActivityIcon())); 778 assertTrue(mPackageManager.isDefaultApplicationIcon(mPackageManager.getDefaultActivityIcon() 779 .getConstantState().newDrawable())); 780 781 assertFalse(mPackageManager.isDefaultApplicationIcon(mPackageManager.getActivityIcon( 782 new ComponentName(PACKAGE_NAME, ACTIVITY_NAME)))); 783 784 // getDrawable is called by ComponentInfo.loadIcon() which called by getActivityIcon() 785 // method of PackageMaganer. Here is just assurance for its functionality. 786 int iconRes = R.drawable.start; 787 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 788 PackageManager.ApplicationInfoFlags.of(0)); 789 assertNotNull(mPackageManager.getDrawable(PACKAGE_NAME, iconRes, appInfo)); 790 } 791 792 @Test testCheckSignaturesMatch_byPackageName()793 public void testCheckSignaturesMatch_byPackageName() { 794 // Compare the signature of this package to another package installed by this test suite 795 // (see AndroidTest.xml). Their signatures must match. 796 assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(PACKAGE_NAME, 797 "com.android.cts.stub")); 798 // This package's signature should match its own signature. 799 assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(PACKAGE_NAME, 800 PACKAGE_NAME)); 801 } 802 803 @Test testCheckSignaturesMatch_byUid()804 public void testCheckSignaturesMatch_byUid() throws NameNotFoundException { 805 // Compare the signature of this package to another package installed by this test suite 806 // (see AndroidTest.xml). Their signatures must match. 807 int uid1 = mPackageManager.getPackageInfo(PACKAGE_NAME, 808 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid; 809 int uid2 = mPackageManager.getPackageInfo("com.android.cts.stub", 810 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid; 811 assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(uid1, uid2)); 812 813 // A UID's signature should match its own signature. 814 assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(uid1, uid1)); 815 } 816 817 @Test testCheckSignaturesNoMatch_byPackageName()818 public void testCheckSignaturesNoMatch_byPackageName() { 819 // This test package's signature shouldn't match the system's signature. 820 assertEquals(PackageManager.SIGNATURE_NO_MATCH, mPackageManager.checkSignatures( 821 PACKAGE_NAME, "android")); 822 } 823 824 @Test testCheckSignaturesNoMatch_byUid()825 public void testCheckSignaturesNoMatch_byUid() throws NameNotFoundException { 826 // This test package's signature shouldn't match the system's signature. 827 int uid1 = mPackageManager.getPackageInfo(PACKAGE_NAME, 828 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid; 829 int uid2 = mPackageManager.getPackageInfo("android", 830 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid; 831 assertEquals(PackageManager.SIGNATURE_NO_MATCH, 832 mPackageManager.checkSignatures(uid1, uid2)); 833 } 834 835 @Test testCheckSignaturesUnknownPackage()836 public void testCheckSignaturesUnknownPackage() { 837 assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, mPackageManager.checkSignatures( 838 PACKAGE_NAME, "this.package.does.not.exist")); 839 } 840 841 @Test testCheckPermissionGranted()842 public void testCheckPermissionGranted() { 843 assertEquals(PackageManager.PERMISSION_GRANTED, 844 mPackageManager.checkPermission(GRANTED_PERMISSION_NAME, PACKAGE_NAME)); 845 } 846 847 @Test testCheckPermissionNotGranted()848 public void testCheckPermissionNotGranted() { 849 assertEquals(PackageManager.PERMISSION_DENIED, 850 mPackageManager.checkPermission(NOT_GRANTED_PERMISSION_NAME, PACKAGE_NAME)); 851 } 852 853 @Test testResolveMethods()854 public void testResolveMethods() { 855 // Test resolveActivity 856 Intent intent = new Intent(ACTIVITY_ACTION_NAME); 857 intent.setComponent(new ComponentName(PACKAGE_NAME, ACTIVITY_NAME)); 858 assertEquals(ACTIVITY_NAME, mPackageManager.resolveActivity(intent, 859 PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY)) 860 .activityInfo.name); 861 862 // Test resolveService 863 intent = new Intent(SERVICE_ACTION_NAME); 864 intent.setComponent(new ComponentName(PACKAGE_NAME, SERVICE_NAME)); 865 ResolveInfo resolveInfo = mPackageManager.resolveService(intent, 866 PackageManager.ResolveInfoFlags.of(0)); 867 assertEquals(SERVICE_NAME, resolveInfo.serviceInfo.name); 868 869 // Test resolveContentProvider 870 String providerAuthorities = "ctstest"; 871 assertEquals(PROVIDER_NAME, 872 mPackageManager.resolveContentProvider(providerAuthorities, 873 PackageManager.ComponentInfoFlags.of(0)).name); 874 } 875 876 @Test testGetResources()877 public void testGetResources() throws NameNotFoundException { 878 ComponentName componentName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME); 879 int resourceId = R.xml.pm_test; 880 String xmlName = "android.content.cts:xml/pm_test"; 881 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 882 PackageManager.ApplicationInfoFlags.of(0)); 883 assertNotNull(mPackageManager.getXml(PACKAGE_NAME, resourceId, appInfo)); 884 assertEquals(xmlName, mPackageManager.getResourcesForActivity(componentName) 885 .getResourceName(resourceId)); 886 assertEquals(xmlName, mPackageManager.getResourcesForApplication(appInfo).getResourceName( 887 resourceId)); 888 assertEquals(xmlName, mPackageManager.getResourcesForApplication(PACKAGE_NAME) 889 .getResourceName(resourceId)); 890 } 891 892 @Test testGetResources_withConfig()893 public void testGetResources_withConfig() throws NameNotFoundException { 894 int resourceId = R.string.config_overridden_string; 895 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 896 PackageManager.ApplicationInfoFlags.of(0)); 897 898 Configuration c1 = new Configuration(mContext.getResources().getConfiguration()); 899 c1.orientation = Configuration.ORIENTATION_PORTRAIT; 900 assertEquals("default", mPackageManager.getResourcesForApplication( 901 appInfo, c1).getString(resourceId)); 902 903 Configuration c2 = new Configuration(mContext.getResources().getConfiguration()); 904 c2.orientation = Configuration.ORIENTATION_LANDSCAPE; 905 assertEquals("landscape", mPackageManager.getResourcesForApplication( 906 appInfo, c2).getString(resourceId)); 907 } 908 909 @Test testGetPackageArchiveInfo()910 public void testGetPackageArchiveInfo() { 911 final String apkPath = mContext.getPackageCodePath(); 912 final String apkName = mContext.getPackageName(); 913 914 PackageInfo pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 915 PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES)); 916 assertEquals("getPackageArchiveInfo should return the correct package name", 917 apkName, pkgInfo.packageName); 918 assertNotNull("SigningInfo should have been collected when GET_SIGNING_CERTIFICATES" 919 + " flag is specified", pkgInfo.signingInfo); 920 921 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 922 PackageManager.PackageInfoFlags.of(GET_SIGNATURES)); 923 assertNotNull("Signatures should have been collected when GET_SIGNATURES" 924 + " flag is specified", pkgInfo.signatures); 925 926 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 927 PackageManager.PackageInfoFlags.of( 928 GET_SIGNATURES | PackageManager.GET_SIGNING_CERTIFICATES)); 929 assertNotNull("SigningInfo should have been collected when" 930 + " GET_SIGNATURES and GET_SIGNING_CERTIFICATES flags are both specified", 931 pkgInfo.signingInfo); 932 assertNotNull("Signatures should have been collected when" 933 + " GET_SIGNATURES and GET_SIGNING_CERTIFICATES flags are both specified", 934 pkgInfo.signatures); 935 936 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 937 PackageManager.PackageInfoFlags.of(GET_ACTIVITIES)); 938 assertNotNull("Activities should have been collected when GET_ACTIVITIES" 939 + " flag is specified", pkgInfo.activities); 940 941 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 942 PackageManager.PackageInfoFlags.of(GET_PROVIDERS)); 943 assertNotNull("Providers should have been collected when GET_PROVIDERS" 944 + " flag is specified", pkgInfo.providers); 945 946 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 947 PackageManager.PackageInfoFlags.of(GET_SERVICES)); 948 assertNotNull("Services should have been collected when GET_SERVICES" 949 + " flag is specified", pkgInfo.services); 950 951 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 952 PackageManager.PackageInfoFlags.of(GET_INSTRUMENTATION)); 953 assertNotNull("Instrumentation should have been collected when GET_INSTRUMENTATION" 954 + " flag is specified", pkgInfo.instrumentation); 955 956 pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath, 957 PackageManager.PackageInfoFlags.of(GET_PERMISSIONS)); 958 assertNotNull("Permissions should have been collected when GET_PERMISSIONS" 959 + " flag is specified", pkgInfo.permissions); 960 } 961 runTestGetPackageArchiveInfoSameApplicationInfo(long flags)962 private void runTestGetPackageArchiveInfoSameApplicationInfo(long flags) { 963 final String apkPath = mContext.getPackageCodePath(); 964 PackageInfo packageInfo = mPackageManager.getPackageArchiveInfo(apkPath, 965 PackageManager.PackageInfoFlags.of(flags)); 966 967 ApplicationInfo applicationInfo = null; 968 if (packageInfo.activities != null) { 969 for (ActivityInfo ac : packageInfo.activities) { 970 if (applicationInfo == null) { 971 applicationInfo = ac.applicationInfo; 972 } else { 973 assertSame(applicationInfo, ac.applicationInfo); 974 } 975 } 976 } 977 if (packageInfo.receivers != null) { 978 for (ActivityInfo ac : packageInfo.receivers) { 979 if (applicationInfo == null) { 980 applicationInfo = ac.applicationInfo; 981 } else { 982 assertSame(applicationInfo, ac.applicationInfo); 983 } 984 } 985 } 986 if (packageInfo.services != null) { 987 for (ServiceInfo si : packageInfo.services) { 988 if (applicationInfo == null) { 989 applicationInfo = si.applicationInfo; 990 } else { 991 assertSame(applicationInfo, si.applicationInfo); 992 } 993 } 994 } 995 if (packageInfo.providers != null) { 996 for (ProviderInfo pi : packageInfo.providers) { 997 if (applicationInfo == null) { 998 applicationInfo = pi.applicationInfo; 999 } else { 1000 assertSame(applicationInfo, pi.applicationInfo); 1001 } 1002 } 1003 } 1004 } 1005 1006 @Test testGetPackageArchiveInfoSameApplicationInfo()1007 public void testGetPackageArchiveInfoSameApplicationInfo() { 1008 runTestGetPackageArchiveInfoSameApplicationInfo(PackageManager.GET_META_DATA); 1009 runTestGetPackageArchiveInfoSameApplicationInfo( 1010 PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES); 1011 runTestGetPackageArchiveInfoSameApplicationInfo( 1012 PackageManager.GET_META_DATA | PackageManager.GET_RECEIVERS); 1013 runTestGetPackageArchiveInfoSameApplicationInfo( 1014 PackageManager.GET_META_DATA | PackageManager.GET_SERVICES); 1015 runTestGetPackageArchiveInfoSameApplicationInfo( 1016 PackageManager.GET_META_DATA | PackageManager.GET_PROVIDERS); 1017 runTestGetPackageArchiveInfoSameApplicationInfo( 1018 PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES 1019 | PackageManager.GET_RECEIVERS); 1020 } 1021 1022 @Test testGetNamesForUids_null()1023 public void testGetNamesForUids_null() throws Exception { 1024 assertNull(mPackageManager.getNamesForUids(null)); 1025 } 1026 1027 @Test testGetNamesForUids_empty()1028 public void testGetNamesForUids_empty() throws Exception { 1029 assertNull(mPackageManager.getNamesForUids(new int[0])); 1030 } 1031 1032 @Test testGetNamesForUids_valid()1033 public void testGetNamesForUids_valid() throws Exception { 1034 final int shimId = 1035 mPackageManager.getApplicationInfo(CTS_SHIM_PACKAGE_NAME, 1036 PackageManager.ApplicationInfoFlags.of(0)).uid; 1037 final int[] uids = new int[]{ 1038 1000, 1039 Integer.MAX_VALUE, 1040 shimId, 1041 }; 1042 final String[] result; 1043 result = mPackageManager.getNamesForUids(uids); 1044 assertNotNull(result); 1045 assertEquals(3, result.length); 1046 assertEquals("shared:android.uid.system", result[0]); 1047 assertEquals(null, result[1]); 1048 assertEquals("shared:com.android.cts.ctsshim", result[2]); 1049 } 1050 1051 @Test testGetPackageUid()1052 public void testGetPackageUid() throws NameNotFoundException { 1053 int userId = mContext.getUserId(); 1054 int expectedUid = UserHandle.getUid(userId, 1000); 1055 1056 assertEquals(expectedUid, mPackageManager.getPackageUid("android", 1057 PackageManager.PackageInfoFlags.of(0))); 1058 1059 int uid = mPackageManager.getApplicationInfo(CTS_SHIM_PACKAGE_NAME, 1060 PackageManager.ApplicationInfoFlags.of(0)).uid; 1061 assertEquals(uid, mPackageManager.getPackageUid(CTS_SHIM_PACKAGE_NAME, 1062 PackageManager.PackageInfoFlags.of(0))); 1063 } 1064 1065 @Test testGetPackageInfo()1066 public void testGetPackageInfo() throws NameNotFoundException { 1067 PackageInfo pkgInfo = mPackageManager.getPackageInfo(PACKAGE_NAME, GET_META_DATA 1068 | GET_PERMISSIONS | GET_ACTIVITIES | GET_PROVIDERS | GET_SERVICES | GET_RECEIVERS); 1069 assertTestPackageInfo(pkgInfo); 1070 } 1071 1072 @Test testPackageSettingsFlags()1073 public void testPackageSettingsFlags() throws Exception { 1074 assertEquals("Success\n", SystemUtil.runShellCommand( 1075 "pm install -t " + HELLO_WORLD_LOTS_OF_FLAGS_APK)); 1076 final String pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, " pkgFlags=["); 1077 assertEquals( 1078 " DEBUGGABLE HAS_CODE ALLOW_TASK_REPARENTING ALLOW_CLEAR_USER_DATA TEST_ONLY " 1079 + "VM_SAFE_MODE ALLOW_BACKUP LARGE_HEAP ]", 1080 pkgFlags); 1081 final String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 1082 " privatePkgFlags=["); 1083 assertEquals( 1084 " PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION " 1085 + "ALLOW_AUDIO_PLAYBACK_CAPTURE " 1086 + "PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING ]", 1087 privatePkgFlags); 1088 } 1089 1090 @Test testGetPackageInfo_notFound()1091 public void testGetPackageInfo_notFound() { 1092 try { 1093 mPackageManager.getPackageInfo("this.package.does.not.exist", 1094 PackageManager.PackageInfoFlags.of(0)); 1095 fail("Exception expected"); 1096 } catch (NameNotFoundException expected) { 1097 } 1098 } 1099 1100 @Test testGetInstalledPackages()1101 public void testGetInstalledPackages() throws Exception { 1102 List<PackageInfo> pkgs = mPackageManager.getInstalledPackages( 1103 PackageManager.PackageInfoFlags.of( 1104 GET_META_DATA | GET_PERMISSIONS | GET_ACTIVITIES | GET_PROVIDERS 1105 | GET_SERVICES | GET_RECEIVERS)); 1106 1107 PackageInfo pkgInfo = findPackageOrFail(pkgs, PACKAGE_NAME); 1108 assertTestPackageInfo(pkgInfo); 1109 } 1110 1111 /** 1112 * Asserts that the pkgInfo object correctly describes the {@link #PACKAGE_NAME} package. 1113 */ assertTestPackageInfo(PackageInfo pkgInfo)1114 private void assertTestPackageInfo(PackageInfo pkgInfo) { 1115 // Check metadata 1116 ApplicationInfo appInfo = pkgInfo.applicationInfo; 1117 assertEquals(APPLICATION_NAME, appInfo.name); 1118 assertEquals("Android TestCase", appInfo.loadLabel(mPackageManager)); 1119 assertEquals(PACKAGE_NAME, appInfo.packageName); 1120 assertTrue(appInfo.enabled); 1121 // The process name defaults to the package name when not set. 1122 assertEquals(PACKAGE_NAME, appInfo.processName); 1123 assertEquals(0, appInfo.flags & FLAG_SYSTEM); 1124 assertEquals(FLAG_INSTALLED, appInfo.flags & FLAG_INSTALLED); 1125 assertEquals(FLAG_HAS_CODE, appInfo.flags & FLAG_HAS_CODE); 1126 1127 // Check required permissions 1128 List<String> requestedPermissions = Arrays.asList(pkgInfo.requestedPermissions); 1129 assertThat(requestedPermissions).containsAtLeast( 1130 "android.permission.MANAGE_ACCOUNTS", 1131 "android.permission.ACCESS_NETWORK_STATE", 1132 "android.content.cts.permission.TEST_GRANTED"); 1133 1134 // Check usesPermissionFlags 1135 boolean requestedAccessFineLocation = false; 1136 boolean requestedAccessCoarseLocation = false; 1137 for (int i = 0; i < pkgInfo.requestedPermissions.length; i++) { 1138 final String name = pkgInfo.requestedPermissions[i]; 1139 final int flags = pkgInfo.requestedPermissionsFlags[i]; 1140 1141 // Verify "never for location" flag 1142 final boolean neverForLocation = (flags 1143 & PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION) != 0; 1144 if ("android.content.cts.permission.TEST_GRANTED".equals(name)) { 1145 assertTrue(name + " with flags " + flags, neverForLocation); 1146 } else { 1147 assertFalse(name + " with flags " + flags, neverForLocation); 1148 } 1149 1150 // Verify "implicit" flag 1151 final boolean hasImplicitFlag = 1152 (flags & PackageInfo.REQUESTED_PERMISSION_IMPLICIT) != 0; 1153 if ("android.permission.ACCESS_FINE_LOCATION".equals(name)) { 1154 assertFalse(name + " with flags " + flags, hasImplicitFlag); 1155 requestedAccessFineLocation = true; 1156 } 1157 if ("android.permission.ACCESS_COARSE_LOCATION".equals(name)) { 1158 assertTrue(name + " with flags " + flags, hasImplicitFlag); 1159 requestedAccessCoarseLocation = true; 1160 } 1161 } 1162 assertTrue("expected ACCESS_FINE_LOCATION to be requested", requestedAccessFineLocation); 1163 assertTrue("expected ACCESS_COARSE_LOCATION to be requested", 1164 requestedAccessCoarseLocation); 1165 1166 // Check declared permissions 1167 PermissionInfo declaredPermission = (PermissionInfo) findPackageItemOrFail( 1168 pkgInfo.permissions, CALL_ABROAD_PERMISSION_NAME); 1169 assertEquals("Call abroad", declaredPermission.loadLabel(mPackageManager)); 1170 assertEquals(PERMISSIONGROUP_NAME, declaredPermission.group); 1171 assertEquals(PermissionInfo.PROTECTION_NORMAL, declaredPermission.protectionLevel); 1172 1173 // Check if number of activities in PackageInfo matches number of activities in manifest, 1174 // to make sure no synthesized activities not in the manifest are returned. 1175 assertEquals("Number of activities in manifest != Number of activities in PackageInfo", 1176 NUM_OF_ACTIVITIES_IN_MANIFEST, pkgInfo.activities.length); 1177 // Check activities 1178 ActivityInfo activity = findPackageItemOrFail(pkgInfo.activities, ACTIVITY_NAME); 1179 assertTrue(activity.enabled); 1180 assertTrue(activity.exported); // Has intent filters - export by default. 1181 assertEquals(PACKAGE_NAME, activity.taskAffinity); 1182 assertEquals(ActivityInfo.LAUNCH_SINGLE_TOP, activity.launchMode); 1183 1184 // Check services 1185 ServiceInfo service = findPackageItemOrFail(pkgInfo.services, SERVICE_NAME); 1186 assertTrue(service.enabled); 1187 assertTrue(service.exported); // Has intent filters - export by default. 1188 assertEquals(PACKAGE_NAME, service.packageName); 1189 assertEquals(CALL_ABROAD_PERMISSION_NAME, service.permission); 1190 1191 // Check ContentProviders 1192 ProviderInfo provider = findPackageItemOrFail(pkgInfo.providers, PROVIDER_NAME); 1193 assertTrue(provider.enabled); 1194 assertEquals(PACKAGE_NAME, provider.packageName); 1195 assertEquals("ctstest", provider.authority); 1196 ProviderInfo nonExportedProvider = 1197 findPackageItemOrFail(pkgInfo.providers, "android.content.cts.MockBuggyProvider"); 1198 assertFalse(nonExportedProvider.exported); // Don't export by default. 1199 1200 // Check Receivers 1201 ActivityInfo receiver = findPackageItemOrFail(pkgInfo.receivers, RECEIVER_NAME); 1202 assertTrue(receiver.enabled); 1203 assertTrue(receiver.exported); // Has intent filters - export by default. 1204 assertEquals(PACKAGE_NAME, receiver.packageName); 1205 } 1206 1207 // Tests that other packages can be queried. 1208 @Test testGetInstalledPackages_OtherPackages()1209 public void testGetInstalledPackages_OtherPackages() throws Exception { 1210 List<PackageInfo> pkgInfos = mPackageManager.getInstalledPackages( 1211 PackageManager.PackageInfoFlags.of(0)); 1212 1213 // Check a normal package. 1214 PackageInfo pkgInfo = findPackageOrFail(pkgInfos, "com.android.cts.stub"); // A test package 1215 assertEquals(0, pkgInfo.applicationInfo.flags & FLAG_SYSTEM); 1216 1217 // Check a system package. 1218 pkgInfo = findPackageOrFail(pkgInfos, "android"); 1219 assertEquals(FLAG_SYSTEM, pkgInfo.applicationInfo.flags & FLAG_SYSTEM); 1220 } 1221 1222 @Test testGetInstalledApplications()1223 public void testGetInstalledApplications() throws Exception { 1224 List<ApplicationInfo> apps = mPackageManager.getInstalledApplications( 1225 PackageManager.ApplicationInfoFlags.of(GET_META_DATA)); 1226 1227 ApplicationInfo app = findPackageItemOrFail( 1228 apps.toArray(new ApplicationInfo[]{}), APPLICATION_NAME); 1229 1230 assertEquals(APPLICATION_NAME, app.name); 1231 assertEquals("Android TestCase", app.loadLabel(mPackageManager)); 1232 assertEquals(PACKAGE_NAME, app.packageName); 1233 assertTrue(app.enabled); 1234 // The process name defaults to the package name when not set. 1235 assertEquals(PACKAGE_NAME, app.processName); 1236 } 1237 findPackageOrFail(List<PackageInfo> pkgInfos, String pkgName)1238 private PackageInfo findPackageOrFail(List<PackageInfo> pkgInfos, String pkgName) { 1239 for (PackageInfo pkgInfo : pkgInfos) { 1240 if (pkgName.equals(pkgInfo.packageName)) { 1241 return pkgInfo; 1242 } 1243 } 1244 fail("Package not found with name " + pkgName); 1245 return null; 1246 } 1247 findPackageItemOrFail(T[] items, String name)1248 private <T extends PackageItemInfo> T findPackageItemOrFail(T[] items, String name) { 1249 for (T item : items) { 1250 if (name.equals(item.name)) { 1251 return item; 1252 } 1253 } 1254 fail("Package item not found with name " + name); 1255 return null; 1256 } 1257 1258 @Test testGetPackagesHoldingPermissions()1259 public void testGetPackagesHoldingPermissions() { 1260 List<PackageInfo> pkgInfos = mPackageManager.getPackagesHoldingPermissions( 1261 new String[]{GRANTED_PERMISSION_NAME}, PackageManager.PackageInfoFlags.of(0)); 1262 findPackageOrFail(pkgInfos, PACKAGE_NAME); 1263 1264 pkgInfos = mPackageManager.getPackagesHoldingPermissions( 1265 new String[]{NOT_GRANTED_PERMISSION_NAME}, 1266 PackageManager.PackageInfoFlags.of(0)); 1267 for (PackageInfo pkgInfo : pkgInfos) { 1268 if (PACKAGE_NAME.equals(pkgInfo.packageName)) { 1269 fail("Must not return package " + PACKAGE_NAME); 1270 } 1271 } 1272 } 1273 1274 @Test testGetPermissionInfo()1275 public void testGetPermissionInfo() throws NameNotFoundException { 1276 // Check a normal permission. 1277 String permissionName = "android.permission.INTERNET"; 1278 PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0); 1279 assertEquals(permissionName, permissionInfo.name); 1280 assertEquals(PermissionInfo.PROTECTION_NORMAL, permissionInfo.getProtection()); 1281 1282 // Check a dangerous (runtime) permission. 1283 permissionName = "android.permission.RECORD_AUDIO"; 1284 permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0); 1285 assertEquals(permissionName, permissionInfo.name); 1286 assertEquals(PermissionInfo.PROTECTION_DANGEROUS, permissionInfo.getProtection()); 1287 assertNotNull(permissionInfo.group); 1288 1289 // Check a signature permission. 1290 permissionName = "android.permission.MODIFY_PHONE_STATE"; 1291 permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0); 1292 assertEquals(permissionName, permissionInfo.name); 1293 assertEquals(PermissionInfo.PROTECTION_SIGNATURE, permissionInfo.getProtection()); 1294 1295 // Check a special access (appop) permission. 1296 permissionName = "android.permission.SYSTEM_ALERT_WINDOW"; 1297 permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0); 1298 assertEquals(permissionName, permissionInfo.name); 1299 assertEquals(PermissionInfo.PROTECTION_SIGNATURE, permissionInfo.getProtection()); 1300 assertEquals(PermissionInfo.PROTECTION_FLAG_APPOP, 1301 permissionInfo.getProtectionFlags() & PermissionInfo.PROTECTION_FLAG_APPOP); 1302 } 1303 1304 @Test testGetPermissionInfo_notFound()1305 public void testGetPermissionInfo_notFound() { 1306 try { 1307 mPackageManager.getPermissionInfo("android.permission.nonexistent.permission", 0); 1308 fail("Exception expected"); 1309 } catch (NameNotFoundException expected) { 1310 } 1311 } 1312 1313 @Test testGetPermissionGroupInfo()1314 public void testGetPermissionGroupInfo() throws NameNotFoundException { 1315 PermissionGroupInfo groupInfo = mPackageManager.getPermissionGroupInfo( 1316 PERMISSIONGROUP_NAME, 0); 1317 assertEquals(PERMISSIONGROUP_NAME, groupInfo.name); 1318 assertEquals(PACKAGE_NAME, groupInfo.packageName); 1319 assertFalse(TextUtils.isEmpty(groupInfo.loadDescription(mPackageManager))); 1320 } 1321 1322 @Test testGetPermissionGroupInfo_notFound()1323 public void testGetPermissionGroupInfo_notFound() throws NameNotFoundException { 1324 try { 1325 mPackageManager.getPermissionGroupInfo("this.group.does.not.exist", 0); 1326 fail("Exception expected"); 1327 } catch (NameNotFoundException expected) { 1328 } 1329 } 1330 1331 @Test testAddPermission_cantAddOutsideRoot()1332 public void testAddPermission_cantAddOutsideRoot() { 1333 PermissionInfo permissionInfo = new PermissionInfo(); 1334 permissionInfo.name = "some.other.permission.tree.some-permission"; 1335 permissionInfo.nonLocalizedLabel = "Some Permission"; 1336 permissionInfo.protectionLevel = PermissionInfo.PROTECTION_NORMAL; 1337 // Remove first 1338 try { 1339 mPackageManager.removePermission(permissionInfo.name); 1340 } catch (SecurityException se) { 1341 } 1342 try { 1343 mPackageManager.addPermission(permissionInfo); 1344 fail("Must not add permission outside the permission tree defined in the manifest."); 1345 } catch (SecurityException expected) { 1346 } 1347 } 1348 1349 @Test testAddPermission()1350 public void testAddPermission() throws NameNotFoundException { 1351 PermissionInfo permissionInfo = new PermissionInfo(); 1352 permissionInfo.name = PERMISSION_TREE_ROOT + ".some-permission"; 1353 permissionInfo.protectionLevel = PermissionInfo.PROTECTION_NORMAL; 1354 permissionInfo.nonLocalizedLabel = "Some Permission"; 1355 // Remove first 1356 try { 1357 mPackageManager.removePermission(permissionInfo.name); 1358 } catch (SecurityException se) { 1359 } 1360 mPackageManager.addPermission(permissionInfo); 1361 PermissionInfo savedInfo = mPackageManager.getPermissionInfo(permissionInfo.name, 0); 1362 assertEquals(PACKAGE_NAME, savedInfo.packageName); 1363 assertEquals(PermissionInfo.PROTECTION_NORMAL, savedInfo.protectionLevel); 1364 } 1365 1366 @Test testSetSystemAppHiddenUntilInstalled()1367 public void testSetSystemAppHiddenUntilInstalled() throws Exception { 1368 String packageToManipulate = CTS_SHIM_PACKAGE_NAME; 1369 try { 1370 mPackageManager.getPackageInfo(packageToManipulate, MATCH_SYSTEM_ONLY); 1371 } catch (NameNotFoundException e) { 1372 Log.i(TAG, "Device doesn't have " + packageToManipulate + " installed, skipping"); 1373 return; 1374 } 1375 1376 try { 1377 SystemUtil.runWithShellPermissionIdentity(() -> 1378 mPackageManager.setSystemAppState(packageToManipulate, 1379 PackageManager.SYSTEM_APP_STATE_UNINSTALLED)); 1380 SystemUtil.runWithShellPermissionIdentity(() -> 1381 mPackageManager.setSystemAppState(packageToManipulate, 1382 SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN)); 1383 1384 // Setting the state to SYSTEM_APP_STATE_UNINSTALLED is an async operation in 1385 // PackageManagerService with no way to listen for completion, so poll until the 1386 // app is no longer found. 1387 int pollingPeriodMs = 100; 1388 int timeoutMs = 1000; 1389 long startTimeMs = SystemClock.elapsedRealtime(); 1390 boolean isAppStillVisible = true; 1391 while (SystemClock.elapsedRealtime() < startTimeMs + timeoutMs) { 1392 try { 1393 mPackageManager.getPackageInfo(packageToManipulate, 1394 PackageManager.PackageInfoFlags.of(MATCH_SYSTEM_ONLY)); 1395 } catch (NameNotFoundException e) { 1396 // expected, stop polling 1397 isAppStillVisible = false; 1398 break; 1399 } 1400 Thread.sleep(pollingPeriodMs); 1401 } 1402 if (isAppStillVisible) { 1403 fail(packageToManipulate + " should not be found via getPackageInfo."); 1404 } 1405 } finally { 1406 SystemUtil.runWithShellPermissionIdentity(() -> 1407 mPackageManager.setSystemAppState(packageToManipulate, 1408 PackageManager.SYSTEM_APP_STATE_INSTALLED)); 1409 SystemUtil.runWithShellPermissionIdentity(() -> 1410 mPackageManager.setSystemAppState(packageToManipulate, 1411 PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE)); 1412 try { 1413 mPackageManager.getPackageInfo(packageToManipulate, 1414 PackageManager.PackageInfoFlags.of(MATCH_SYSTEM_ONLY)); 1415 } catch (NameNotFoundException e) { 1416 fail(packageToManipulate 1417 + " should be found via getPackageInfo after re-enabling."); 1418 } 1419 } 1420 } 1421 1422 @Test testGetPackageInfo_ApexSupported_ApexPackage_MatchesApex()1423 public void testGetPackageInfo_ApexSupported_ApexPackage_MatchesApex() throws Exception { 1424 final int flags = PackageManager.MATCH_APEX 1425 | PackageManager.MATCH_FACTORY_ONLY 1426 | PackageManager.GET_SIGNING_CERTIFICATES 1427 | GET_SIGNATURES; 1428 PackageInfo packageInfo = mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, 1429 PackageManager.PackageInfoFlags.of(flags)); 1430 assertShimApexInfoIsCorrect(packageInfo); 1431 } 1432 1433 @Test testGetPackageInfo_ApexSupported_ApexPackage_DoesNotMatchApex()1434 public void testGetPackageInfo_ApexSupported_ApexPackage_DoesNotMatchApex() { 1435 try { 1436 mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, 1437 PackageManager.PackageInfoFlags.of(0)); 1438 fail("NameNotFoundException expected"); 1439 } catch (NameNotFoundException expected) { 1440 } 1441 } 1442 1443 @Test testGetInstalledPackages_ApexSupported_MatchesApex()1444 public void testGetInstalledPackages_ApexSupported_MatchesApex() { 1445 final int flags = PackageManager.MATCH_APEX 1446 | PackageManager.MATCH_FACTORY_ONLY 1447 | PackageManager.GET_SIGNING_CERTIFICATES 1448 | GET_SIGNATURES; 1449 List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages( 1450 PackageManager.PackageInfoFlags.of(flags)); 1451 List<PackageInfo> shimApex = installedPackages.stream().filter( 1452 packageInfo -> packageInfo.packageName.equals(SHIM_APEX_PACKAGE_NAME)).collect( 1453 Collectors.toList()); 1454 assertWithMessage("More than one shim apex found").that(shimApex).hasSize(1); 1455 assertShimApexInfoIsCorrect(shimApex.get(0)); 1456 } 1457 1458 @Test testGetInstalledPackages_ApexSupported_DoesNotMatchApex()1459 public void testGetInstalledPackages_ApexSupported_DoesNotMatchApex() { 1460 List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages( 1461 PackageManager.PackageInfoFlags.of(0)); 1462 List<PackageInfo> shimApex = installedPackages.stream().filter( 1463 packageInfo -> packageInfo.packageName.equals(SHIM_APEX_PACKAGE_NAME)).collect( 1464 Collectors.toList()); 1465 assertWithMessage("Shim apex wasn't supposed to be found").that(shimApex).isEmpty(); 1466 } 1467 1468 @Test 1469 @RequiresFlagsEnabled(FLAG_PROVIDE_INFO_OF_APK_IN_APEX) testGetPackageInfo_apex_hasApexPackageName()1470 public void testGetPackageInfo_apex_hasApexPackageName() throws Exception { 1471 PackageInfo packageInfo = 1472 mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX); 1473 1474 assertThat(packageInfo.packageName).isEqualTo(SHIM_APEX_PACKAGE_NAME); 1475 assertThat(packageInfo.getApexPackageName()).isEqualTo(SHIM_APEX_PACKAGE_NAME); 1476 } 1477 1478 @Test 1479 @RequiresFlagsEnabled(FLAG_PROVIDE_INFO_OF_APK_IN_APEX) testGetPackageInfo_apkInApex_hasApexPackageName()1480 public void testGetPackageInfo_apkInApex_hasApexPackageName() 1481 throws Exception { 1482 PackageInfo packageInfo = 1483 mPackageManager.getPackageInfo(CTS_SHIM_PACKAGE_NAME, /* flags= */ 0); 1484 1485 assertThat(packageInfo.packageName).isEqualTo(CTS_SHIM_PACKAGE_NAME); 1486 assertThat(packageInfo.getApexPackageName()).isEqualTo(SHIM_APEX_PACKAGE_NAME); 1487 } 1488 1489 @Test 1490 @RequiresFlagsEnabled(FLAG_PROVIDE_INFO_OF_APK_IN_APEX) testGetPackageInfo_normalApk_noApexPackageName()1491 public void testGetPackageInfo_normalApk_noApexPackageName() throws Exception { 1492 PackageInfo packageInfo = 1493 mPackageManager.getPackageInfo(PACKAGE_NAME, /* flags= */ 0); 1494 1495 assertThat(packageInfo.packageName).isEqualTo(PACKAGE_NAME); 1496 assertThat(packageInfo.getApexPackageName()).isNull(); 1497 } 1498 1499 /** 1500 * Test that {@link ComponentInfo#metaData} data associated with all components in this 1501 * package will only be filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1502 */ 1503 @Test testGetInfo_noMetaData_InPackage()1504 public void testGetInfo_noMetaData_InPackage() throws Exception { 1505 final PackageInfo info = mPackageManager.getPackageInfo(PACKAGE_NAME, 1506 PackageManager.PackageInfoFlags.of( 1507 GET_ACTIVITIES | GET_SERVICES | GET_RECEIVERS | GET_PROVIDERS)); 1508 1509 assertThat(info.applicationInfo.metaData).isNull(); 1510 Arrays.stream(info.activities).forEach(i -> assertThat(i.metaData).isNull()); 1511 Arrays.stream(info.services).forEach(i -> assertThat(i.metaData).isNull()); 1512 Arrays.stream(info.receivers).forEach(i -> assertThat(i.metaData).isNull()); 1513 Arrays.stream(info.providers).forEach(i -> assertThat(i.metaData).isNull()); 1514 } 1515 1516 /** 1517 * Test that {@link ComponentInfo#metaData} data associated with this application will only be 1518 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1519 */ 1520 @Test testGetInfo_noMetaData_InApplication()1521 public void testGetInfo_noMetaData_InApplication() throws Exception { 1522 final ApplicationInfo ai = mPackageManager.getApplicationInfo(PACKAGE_NAME, 1523 PackageManager.ApplicationInfoFlags.of(0)); 1524 assertThat(ai.metaData).isNull(); 1525 } 1526 1527 /** 1528 * Test that {@link ComponentInfo#metaData} data associated with this activity will only be 1529 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1530 */ 1531 @Test testGetInfo_noMetaData_InActivity()1532 public void testGetInfo_noMetaData_InActivity() throws Exception { 1533 final ComponentName componentName = new ComponentName(mContext, MockActivity.class); 1534 final ActivityInfo info = mPackageManager.getActivityInfo(componentName, 1535 PackageManager.ComponentInfoFlags.of(0)); 1536 assertThat(info.metaData).isNull(); 1537 } 1538 1539 /** 1540 * Test that {@link ComponentInfo#metaData} data associated with this service will only be 1541 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1542 */ 1543 @Test testGetInfo_noMetaData_InService()1544 public void testGetInfo_noMetaData_InService() throws Exception { 1545 final ComponentName componentName = new ComponentName(mContext, MockService.class); 1546 final ServiceInfo info = mPackageManager.getServiceInfo(componentName, 1547 PackageManager.ComponentInfoFlags.of(0)); 1548 assertThat(info.metaData).isNull(); 1549 } 1550 1551 /** 1552 * Test that {@link ComponentInfo#metaData} data associated with this receiver will only be 1553 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1554 */ 1555 @Test testGetInfo_noMetaData_InBroadcastReceiver()1556 public void testGetInfo_noMetaData_InBroadcastReceiver() throws Exception { 1557 final ComponentName componentName = new ComponentName(mContext, MockReceiver.class); 1558 final ActivityInfo info = mPackageManager.getReceiverInfo(componentName, 1559 PackageManager.ComponentInfoFlags.of(0)); 1560 assertThat(info.metaData).isNull(); 1561 } 1562 1563 /** 1564 * Test that {@link ComponentInfo#metaData} data associated with this provider will only be 1565 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1566 */ 1567 @Test testGetInfo_noMetaData_InContentProvider()1568 public void testGetInfo_noMetaData_InContentProvider() throws Exception { 1569 final ComponentName componentName = new ComponentName(mContext, MockContentProvider.class); 1570 final ProviderInfo info = mPackageManager.getProviderInfo(componentName, 1571 PackageManager.ComponentInfoFlags.of(0)); 1572 assertThat(info.metaData).isNull(); 1573 } 1574 1575 /** 1576 * Test that {@link ComponentInfo#metaData} data associated with all components in this 1577 * package will not be filled in if the {@link PackageManager#GET_META_DATA} flag is not set. 1578 */ 1579 @Test testGetInfo_checkMetaData_InPackage()1580 public void testGetInfo_checkMetaData_InPackage() throws Exception { 1581 final PackageInfo info = mPackageManager.getPackageInfo(PACKAGE_NAME, 1582 PackageManager.PackageInfoFlags.of( 1583 GET_META_DATA | GET_ACTIVITIES | GET_SERVICES | GET_RECEIVERS 1584 | GET_PROVIDERS)); 1585 1586 checkMetaData(new PackageItemInfo(info.applicationInfo)); 1587 checkMetaData(new PackageItemInfo( 1588 findPackageItemOrFail(info.activities, "android.content.cts.MockActivity"))); 1589 checkMetaData(new PackageItemInfo( 1590 findPackageItemOrFail(info.services, "android.content.cts.MockService"))); 1591 checkMetaData(new PackageItemInfo( 1592 findPackageItemOrFail(info.receivers, "android.content.cts.MockReceiver"))); 1593 checkMetaData(new PackageItemInfo( 1594 findPackageItemOrFail(info.providers, "android.content.cts.MockContentProvider"))); 1595 } 1596 1597 /** 1598 * Test that {@link ComponentInfo#metaData} data associated with this application will only be 1599 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1600 */ 1601 @Test testGetInfo_checkMetaData_InApplication()1602 public void testGetInfo_checkMetaData_InApplication() throws Exception { 1603 final ApplicationInfo ai = mPackageManager.getApplicationInfo(PACKAGE_NAME, 1604 PackageManager.ApplicationInfoFlags.of(GET_META_DATA)); 1605 checkMetaData(new PackageItemInfo(ai)); 1606 } 1607 1608 /** 1609 * Test that {@link ComponentInfo#metaData} data associated with this activity will only be 1610 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1611 */ 1612 @Test testGetInfo_checkMetaData_InActivity()1613 public void testGetInfo_checkMetaData_InActivity() throws Exception { 1614 final ComponentName componentName = new ComponentName(mContext, MockActivity.class); 1615 final ActivityInfo ai = mPackageManager.getActivityInfo(componentName, 1616 PackageManager.ComponentInfoFlags.of(GET_META_DATA)); 1617 checkMetaData(new PackageItemInfo(ai)); 1618 } 1619 1620 /** 1621 * Test that {@link ComponentInfo#metaData} data associated with this service will only be 1622 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1623 */ 1624 @Test testGetInfo_checkMetaData_InService()1625 public void testGetInfo_checkMetaData_InService() throws Exception { 1626 final ComponentName componentName = new ComponentName(mContext, MockService.class); 1627 final ServiceInfo info = mPackageManager.getServiceInfo(componentName, 1628 PackageManager.ComponentInfoFlags.of(GET_META_DATA)); 1629 checkMetaData(new PackageItemInfo(info)); 1630 } 1631 1632 /** 1633 * Test that {@link ComponentInfo#metaData} data associated with this receiver will only be 1634 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1635 */ 1636 @Test testGetInfo_checkMetaData_InBroadcastReceiver()1637 public void testGetInfo_checkMetaData_InBroadcastReceiver() throws Exception { 1638 final ComponentName componentName = new ComponentName(mContext, MockReceiver.class); 1639 final ActivityInfo info = mPackageManager.getReceiverInfo(componentName, 1640 PackageManager.ComponentInfoFlags.of(GET_META_DATA)); 1641 checkMetaData(new PackageItemInfo(info)); 1642 } 1643 1644 /** 1645 * Test that {@link ComponentInfo#metaData} data associated with this provider will only be 1646 * filled in if the {@link PackageManager#GET_META_DATA} flag is set. 1647 */ 1648 @Test testGetInfo_checkMetaData_InContentProvider()1649 public void testGetInfo_checkMetaData_InContentProvider() throws Exception { 1650 final ComponentName componentName = new ComponentName(mContext, MockContentProvider.class); 1651 final ProviderInfo info = mPackageManager.getProviderInfo(componentName, 1652 PackageManager.ComponentInfoFlags.of(GET_META_DATA)); 1653 checkMetaData(new PackageItemInfo(info)); 1654 } 1655 checkMetaData(@onNull PackageItemInfo ci)1656 private void checkMetaData(@NonNull PackageItemInfo ci) 1657 throws IOException, XmlPullParserException, NameNotFoundException { 1658 final Bundle metaData = ci.metaData; 1659 final Resources res = mPackageManager.getResourcesForApplication(ci.packageName); 1660 assertWithMessage("No meta-data found").that(metaData).isNotNull(); 1661 1662 assertThat(metaData.getString("android.content.cts.string")).isEqualTo("foo"); 1663 assertThat(metaData.getBoolean("android.content.cts.boolean")).isTrue(); 1664 assertThat(metaData.getInt("android.content.cts.integer")).isEqualTo(100); 1665 assertThat(metaData.getInt("android.content.cts.color")).isEqualTo(0xff000000); 1666 assertThat(metaData.getFloat("android.content.cts.float")).isEqualTo(100.1f); 1667 assertThat(metaData.getInt("android.content.cts.reference")).isEqualTo(R.xml.metadata); 1668 1669 XmlResourceParser xml = null; 1670 TypedArray a = null; 1671 try { 1672 xml = ci.loadXmlMetaData(mPackageManager, "android.content.cts.reference"); 1673 assertThat(xml).isNotNull(); 1674 1675 int type; 1676 while ((type = xml.next()) != XmlPullParser.START_TAG 1677 && type != XmlPullParser.END_DOCUMENT) { 1678 // Seek parser to start tag. 1679 } 1680 assertThat(type).isEqualTo(XmlPullParser.START_TAG); 1681 assertThat(xml.getName()).isEqualTo("thedata"); 1682 1683 assertThat(xml.getAttributeValue(null, "rawText")).isEqualTo("some raw text"); 1684 assertThat(xml.getAttributeIntValue(null, "rawColor", 0)).isEqualTo(0xffffff00); 1685 assertThat(xml.getAttributeValue(null, "rawColor")).isEqualTo("#ffffff00"); 1686 1687 a = res.obtainAttributes(xml, new int[]{android.R.attr.text, android.R.attr.color}); 1688 assertThat(a.getString(0)).isEqualTo("metadata text"); 1689 assertThat(a.getColor(1, 0)).isEqualTo(0xffff0000); 1690 assertThat(a.getString(1)).isEqualTo("#ffff0000"); 1691 } finally { 1692 if (a != null) { 1693 a.recycle(); 1694 } 1695 if (xml != null) { 1696 xml.close(); 1697 } 1698 } 1699 } 1700 1701 @Test testGetApplicationInfo_ApexSupported_MatchesApex()1702 public void testGetApplicationInfo_ApexSupported_MatchesApex() throws Exception { 1703 ApplicationInfo ai = mPackageManager.getApplicationInfo( 1704 SHIM_APEX_PACKAGE_NAME, 1705 PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_APEX)); 1706 assertThat(ai.sourceDir).isEqualTo("/system/apex/com.android.apex.cts.shim.apex"); 1707 assertThat(ai.publicSourceDir).isEqualTo(ai.sourceDir); 1708 assertThat(ai.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(ApplicationInfo.FLAG_SYSTEM); 1709 assertThat(ai.flags & ApplicationInfo.FLAG_INSTALLED) 1710 .isEqualTo(ApplicationInfo.FLAG_INSTALLED); 1711 } 1712 1713 @Test testGetApplicationInfo_icon_MatchesUseRoundIcon()1714 public void testGetApplicationInfo_icon_MatchesUseRoundIcon() throws Exception { 1715 installPackage(HELLO_WORLD_APK); 1716 final boolean useRoundIcon = mContext.getResources().getBoolean( 1717 mContext.getResources().getIdentifier("config_useRoundIcon", "bool", "android")); 1718 final ApplicationInfo info = mPackageManager.getApplicationInfo(HELLO_WORLD_PACKAGE_NAME, 1719 PackageManager.ApplicationInfoFlags.of(0)); 1720 assertThat(info.icon).isEqualTo((useRoundIcon ? info.roundIconRes : info.iconRes)); 1721 } 1722 assertShimApexInfoIsCorrect(PackageInfo packageInfo)1723 private static void assertShimApexInfoIsCorrect(PackageInfo packageInfo) { 1724 assertThat(packageInfo.packageName).isEqualTo(SHIM_APEX_PACKAGE_NAME); 1725 assertThat(packageInfo.getLongVersionCode()).isEqualTo(1); 1726 assertThat(packageInfo.isApex).isTrue(); 1727 assertThat(packageInfo.applicationInfo.sourceDir).isEqualTo( 1728 "/system/apex/com.android.apex.cts.shim.apex"); 1729 assertThat(packageInfo.applicationInfo.publicSourceDir) 1730 .isEqualTo(packageInfo.applicationInfo.sourceDir); 1731 // Verify that legacy mechanism for handling signatures is supported. 1732 Signature[] pastSigningCertificates = 1733 packageInfo.signingInfo.getSigningCertificateHistory(); 1734 assertThat(packageInfo.signatures) 1735 .asList().containsExactly((Object[]) pastSigningCertificates); 1736 } 1737 1738 /** 1739 * Runs a test for all combinations of a set of flags 1740 * 1741 * @param flagValues Which flags to use 1742 * @param test The test 1743 */ runTestWithFlags(int[] flagValues, Consumer<Integer> test)1744 public void runTestWithFlags(int[] flagValues, Consumer<Integer> test) { 1745 for (int i = 0; i < (1 << flagValues.length); i++) { 1746 int flags = 0; 1747 for (int j = 0; j < flagValues.length; j++) { 1748 if ((i & (1 << j)) != 0) { 1749 flags |= flagValues[j]; 1750 } 1751 } 1752 try { 1753 test.accept(flags); 1754 } catch (Throwable t) { 1755 throw new AssertionError( 1756 "Test failed for flags 0x" + String.format("%08x", flags), t); 1757 } 1758 } 1759 } 1760 1761 /** 1762 * Test that the MATCH_FACTORY_ONLY flag doesn't add new package names in the result of 1763 * getInstalledPackages. 1764 */ 1765 @Test testGetInstalledPackages_WithFactoryFlag_IsSubset()1766 public void testGetInstalledPackages_WithFactoryFlag_IsSubset() { 1767 runTestWithFlags(PACKAGE_INFO_MATCH_FLAGS, 1768 this::testGetInstalledPackages_WithFactoryFlag_IsSubset); 1769 } 1770 testGetInstalledPackages_WithFactoryFlag_IsSubset(int flags)1771 public void testGetInstalledPackages_WithFactoryFlag_IsSubset(int flags) { 1772 List<PackageInfo> packageInfos = mPackageManager.getInstalledPackages( 1773 PackageManager.PackageInfoFlags.of(flags)); 1774 List<PackageInfo> packageInfos2 = mPackageManager.getInstalledPackages( 1775 PackageManager.PackageInfoFlags.of(flags | MATCH_FACTORY_ONLY)); 1776 Set<String> supersetNames = 1777 packageInfos.stream().map(pi -> pi.packageName).collect(Collectors.toSet()); 1778 1779 for (PackageInfo pi : packageInfos2) { 1780 if (!supersetNames.contains(pi.packageName)) { 1781 throw new AssertionError( 1782 "The subset contains packages that the superset doesn't contain."); 1783 } 1784 } 1785 } 1786 1787 /** 1788 * Test that the MATCH_FACTORY_ONLY flag filters out all non-system packages in the result of 1789 * getInstalledPackages. 1790 */ 1791 @Test testGetInstalledPackages_WithFactoryFlag_ImpliesSystem()1792 public void testGetInstalledPackages_WithFactoryFlag_ImpliesSystem() { 1793 runTestWithFlags(PACKAGE_INFO_MATCH_FLAGS, 1794 this::testGetInstalledPackages_WithFactoryFlag_ImpliesSystem); 1795 } 1796 testGetInstalledPackages_WithFactoryFlag_ImpliesSystem(int flags)1797 public void testGetInstalledPackages_WithFactoryFlag_ImpliesSystem(int flags) { 1798 List<PackageInfo> packageInfos = 1799 mPackageManager.getInstalledPackages( 1800 PackageManager.PackageInfoFlags.of(flags | MATCH_FACTORY_ONLY)); 1801 for (PackageInfo pi : packageInfos) { 1802 if (!pi.applicationInfo.isSystemApp()) { 1803 throw new AssertionError(pi.packageName + " is not a system app."); 1804 } 1805 } 1806 } 1807 1808 /** 1809 * Test that we con't have conflicting package names between APK and APEX. 1810 */ 1811 @Test testGetInstalledPackages_WithApexFlag_ContainsNoDuplicates()1812 public void testGetInstalledPackages_WithApexFlag_ContainsNoDuplicates() { 1813 List<PackageInfo> packageInfos = mPackageManager.getInstalledPackages( 1814 PackageManager.PackageInfoFlags.of(MATCH_APEX)); 1815 final Set<String> apexPackageNames = packageInfos.stream() 1816 .filter(pi -> pi.isApex).map(pi -> pi.packageName).collect(Collectors.toSet()); 1817 final Set<String> apkPackageNames = packageInfos.stream() 1818 .filter(pi -> !pi.isApex).map(pi -> pi.packageName).collect(Collectors.toSet()); 1819 for (String packageName : apkPackageNames) { 1820 if (apexPackageNames.contains(packageName)) { 1821 expect.withMessage("Conflicting APK package " + packageName + " detected").fail(); 1822 } 1823 } 1824 } 1825 1826 /** 1827 * Test that the MATCH_FACTORY_ONLY flag doesn't add the same package multiple times since there 1828 * may be multiple versions of a system package on the device. 1829 */ 1830 @Test testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates()1831 public void testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates() { 1832 final Set<String> packageNames = new HashSet<>(); 1833 runTestWithFlags(PACKAGE_INFO_MATCH_FLAGS, 1834 flags -> testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates(flags, 1835 packageNames)); 1836 } 1837 testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates(int flags, Set<String> packageNames)1838 public void testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates(int flags, 1839 Set<String> packageNames) { 1840 List<PackageInfo> packageInfos = 1841 mPackageManager.getInstalledPackages( 1842 PackageManager.PackageInfoFlags.of(flags | MATCH_FACTORY_ONLY)); 1843 1844 final Set<String> localPackageNames = new HashSet<>(); 1845 for (PackageInfo pi : packageInfos) { 1846 final String packageName = pi.packageName; 1847 // Duplicate: already in local. 1848 // Dedup error messages: not in global. 1849 if (!localPackageNames.add(pi.packageName) && packageNames.add(packageName)) { 1850 expect.withMessage("Duplicate package " + packageName + " detected").fail(); 1851 } 1852 } 1853 } 1854 1855 @Test testInstallTestOnlyPackagePermission_onlyGrantedToShell()1856 public void testInstallTestOnlyPackagePermission_onlyGrantedToShell() { 1857 List<PackageInfo> packages = mPackageManager.getPackagesHoldingPermissions( 1858 new String[]{INSTALL_TEST_ONLY_PACKAGE}, PackageManager.PackageInfoFlags.of(0)); 1859 1860 assertThat(packages).hasSize(1); 1861 assertThat(packages.get(0).packageName).isEqualTo(SHELL_PACKAGE_NAME); 1862 } 1863 1864 @Test testInstall_withLongPackageName_fail()1865 public void testInstall_withLongPackageName_fail() { 1866 assertThat(installPackage(LONG_PACKAGE_NAME_APK)).isFalse(); 1867 } 1868 1869 @Test testInstall_withLongSharedUserId_fail()1870 public void testInstall_withLongSharedUserId_fail() { 1871 assertThat(installPackage(LONG_SHARED_USER_ID_APK)).isFalse(); 1872 } 1873 1874 @Test testInstall_withMaxPackageName_success()1875 public void testInstall_withMaxPackageName_success() { 1876 assertThat(installPackage(MAX_PACKAGE_NAME_APK)).isTrue(); 1877 } 1878 1879 @Test testInstall_withMaxSharedUserId_success()1880 public void testInstall_withMaxSharedUserId_success() { 1881 assertThat(installPackage(MAX_SHARED_USER_ID_APK)).isTrue(); 1882 } 1883 1884 @Test testInstall_withLongUsesPermissionName_fail()1885 public void testInstall_withLongUsesPermissionName_fail() { 1886 String expectedErrorCode = "INSTALL_PARSE_FAILED"; 1887 String installResult = installPackageWithResult(LONG_USES_PERMISSION_NAME_APK); 1888 assertThat(installResult).contains(expectedErrorCode); 1889 } 1890 1891 @Test testUpdateShellFailed()1892 public void testUpdateShellFailed() throws Exception { 1893 // First make sure that shell is not updatable, otherwise the test would eventually fail 1894 // and put the system in bad state. 1895 String isShellUpdatable = parsePackageDump(SHELL_PACKAGE_NAME, " updatableSystem="); 1896 assertThat(isShellUpdatable).contains("false"); 1897 1898 var result = SystemUtil.runShellCommand("pm install -t -g " + SHELL_NAME_APK); 1899 boolean installationNotAllowed = result.contains( 1900 "Installation of this package is not allowed"); 1901 // This test works correctly if platform and cts are built using the same certificate. 1902 // Otherwise the install will still fail, but for a different reason. 1903 boolean signatureMismatch = result.contains( 1904 "signatures do not match newer version"); 1905 assertTrue(installationNotAllowed || signatureMismatch); 1906 } 1907 1908 @Test testInstallNonUpdatableSystemFailed()1909 public void testInstallNonUpdatableSystemFailed() { 1910 installPackage(HELLO_WORLD_APK); 1911 assertThat(SystemUtil.runShellCommand( 1912 "pm install -t -g " + HELLO_WORLD_NON_UPDATABLE_SYSTEM_APK)).contains( 1913 "Non updatable system package"); 1914 } 1915 1916 @Test testSharedUidMaxSdkVersion()1917 public void testSharedUidMaxSdkVersion() throws Exception { 1918 assertThat(installPackageWithResult(HELLO_WORLD_SHARED_UID_APK)).isEqualTo("Success\n"); 1919 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 1920 String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 1921 " privatePkgFlags=["); 1922 assertThat(privatePkgFlags).doesNotContain("PRIVILEGED"); 1923 } 1924 1925 @Test 1926 @RequiresFlagsEnabled(FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS) testInstallAppSharedSystemUidAllowlisted()1927 public void testInstallAppSharedSystemUidAllowlisted() { 1928 var result = SystemUtil.runShellCommand("pm install -t -g " + HELLO_WORLD_SETTINGS); 1929 if (result.contains("no signatures that match those in shared user android.uid.system")) { 1930 // This is a <unit> test, not a proper CTS. 1931 // While certificate for HelloWorldSettings is "platform", it might not be THE platform. 1932 // This test works correctly if platform and cts are built using the same certificate. 1933 // Otherwise the install will still fail, but for a different reason. 1934 return; 1935 } 1936 assertThat(result).isEqualTo("Success\n"); 1937 uninstallPackage(HELLO_WORLD_SETTINGS_PACKAGE_NAME); 1938 } 1939 1940 @Test 1941 @RequiresFlagsEnabled(FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS) testInstallAppSharedSystemUid()1942 public void testInstallAppSharedSystemUid() { 1943 var result = SystemUtil.runShellCommand("pm install -t -g " + HELLO_WORLD_SETTINGS2); 1944 if (result.contains("no signatures that match those in shared user android.uid.system")) { 1945 // This is a <unit> test, not a proper CTS. 1946 // While certificate for HelloWorldSettings is "platform", it might not be THE platform. 1947 // This test works correctly if platform and cts are built using the same certificate. 1948 // Otherwise the install will still fail, but for a different reason. 1949 return; 1950 } 1951 if (!Build.IS_DEBUGGABLE) { 1952 assertThat(result).contains("Non-preload app " + HELLO_WORLD_SETTINGS2_PACKAGE_NAME 1953 + " signed with platform signature and joining shared uid"); 1954 } else { 1955 assertThat(result).isEqualTo("Success\n"); 1956 uninstallPackage(HELLO_WORLD_SETTINGS2_PACKAGE_NAME); 1957 } 1958 } 1959 1960 @Test testUpdateSystemApp()1961 public void testUpdateSystemApp() throws Exception { 1962 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(SETTINGS_PROVIDER_PACKAGE_NAME, 1963 PackageManager.ApplicationInfoFlags.of(0)); 1964 assertNotNull(appInfo.getBaseCodePath()); 1965 assertThat(installPackageWithResult(appInfo.getBaseCodePath())).isEqualTo("Success\n"); 1966 } 1967 installPackageWithResult(String apkPath)1968 private String installPackageWithResult(String apkPath) { 1969 return SystemUtil.runShellCommand("pm install -t " + apkPath); 1970 } 1971 installPackage(String apkPath)1972 private boolean installPackage(String apkPath) { 1973 return SystemUtil.runShellCommand( 1974 "pm install -t " + apkPath).equals("Success\n"); 1975 } 1976 installPackage(String apkPath, String expectedResultStartsWith)1977 private void installPackage(String apkPath, String expectedResultStartsWith) 1978 throws IOException { 1979 String result = SystemUtil.runShellCommand("pm install -t -g " + apkPath); 1980 assertTrue(result, result.startsWith(expectedResultStartsWith)); 1981 } 1982 addSplitDontKill(String packageName, String splitPath)1983 private boolean addSplitDontKill(String packageName, String splitPath) { 1984 return SystemUtil.runShellCommand( 1985 "pm install-streaming -p " + packageName + " --dont-kill -t " + splitPath).equals( 1986 "Success\n"); 1987 } 1988 installPackageWithInstallerPkgName(String apkPath, String installerName)1989 private void installPackageWithInstallerPkgName(String apkPath, String installerName) 1990 throws IOException { 1991 File file = new File(apkPath); 1992 assertEquals("Success\n", SystemUtil.runShellCommand( 1993 "pm install -i " + installerName + " -t -g " + file.getPath())); 1994 } 1995 uninstallPackage(String packageName)1996 private void uninstallPackage(String packageName) { 1997 SystemUtil.runShellCommand("pm uninstall " + packageName); 1998 } 1999 uninstallPackageForUser(String packageName, int userId)2000 private void uninstallPackageForUser(String packageName, int userId) { 2001 SystemUtil.runShellCommand("pm uninstall --user " + userId + " " + packageName); 2002 2003 } 2004 installExistingPackageForUser(String packageName, int userId)2005 private void installExistingPackageForUser(String packageName, int userId) { 2006 SystemUtil.runShellCommand("pm install-existing --user " + userId + " " + packageName); 2007 } 2008 uninstallPackageKeepData(String packageName)2009 private void uninstallPackageKeepData(String packageName) { 2010 SystemUtil.runShellCommand("pm uninstall -k " + packageName); 2011 } 2012 uninstallPackageKeepDataForUser(String packageName, int userId)2013 private void uninstallPackageKeepDataForUser(String packageName, int userId) { 2014 SystemUtil.runShellCommand("pm uninstall -k --user " + userId + " " + packageName); 2015 } 2016 isAppInstalled(String packageName)2017 private static boolean isAppInstalled(String packageName) { 2018 return isPackagePresent(packageName, /*matchAllPackages=*/false); 2019 } 2020 isPackagePresent(String packageName)2021 private static boolean isPackagePresent(String packageName) { 2022 return isPackagePresent(packageName, /*matchAllPackages=*/true); 2023 } 2024 isPackagePresent(String packageName, boolean matchAllPackages)2025 private static boolean isPackagePresent(String packageName, boolean matchAllPackages) { 2026 final String commandResult = 2027 SystemUtil.runShellCommand("pm list packages" + (matchAllPackages ? " -a" : "")); 2028 final int prefixLength = "package:".length(); 2029 return Arrays.stream(commandResult.split("\\r?\\n")).anyMatch( 2030 line -> line.length() > prefixLength && line.substring(prefixLength).equals( 2031 packageName)); 2032 } 2033 executeShellCommand(String command, byte[] input)2034 static String executeShellCommand(String command, byte[] input) throws IOException { 2035 var instrumentation = InstrumentationRegistry.getInstrumentation(); 2036 final ParcelFileDescriptor[] pfds = 2037 instrumentation.getUiAutomation().executeShellCommandRw( 2038 command); 2039 ParcelFileDescriptor stdout = pfds[0]; 2040 ParcelFileDescriptor stdin = pfds[1]; 2041 try (FileOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream( 2042 stdin)) { 2043 outputStream.write(input); 2044 } 2045 try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) { 2046 return new String(FileUtils.readInputStreamFully(inputStream)); 2047 } 2048 } 2049 2050 installArchived(ArchivedPackageInfo archivedPackageInfo)2051 private void installArchived(ArchivedPackageInfo archivedPackageInfo) 2052 throws Exception { 2053 installArchived(archivedPackageInfo, 2054 STATUS_SUCCESS, /* expectedResultStartsWith= */ null); 2055 } 2056 installArchived(ArchivedPackageInfo archivedPackageInfo, int expectedStatus, String expectedResultStartsWith)2057 private void installArchived(ArchivedPackageInfo archivedPackageInfo, int expectedStatus, 2058 String expectedResultStartsWith) throws Exception { 2059 installArchivedAsUser( 2060 archivedPackageInfo, expectedStatus, expectedResultStartsWith, mContext.getUser()); 2061 } 2062 installArchivedAsUser(ArchivedPackageInfo archivedPackageInfo, int expectedStatus, String expectedResultStartsWith, UserHandle user)2063 static void installArchivedAsUser(ArchivedPackageInfo archivedPackageInfo, int expectedStatus, 2064 String expectedResultStartsWith, UserHandle user) throws Exception { 2065 var instrumentation = InstrumentationRegistry.getInstrumentation(); 2066 var userContext = instrumentation.getContext().createContextAsUser(user, 0); 2067 var packageInstaller = userContext.getPackageManager().getPackageInstaller(); 2068 final CompletableFuture<Integer> status = new CompletableFuture<>(); 2069 final CompletableFuture<String> statusMessage = new CompletableFuture<>(); 2070 SystemUtil.runWithShellPermissionIdentity(instrumentation.getUiAutomation(), () -> { 2071 var params = new SessionParams(MODE_FULL_INSTALL); 2072 packageInstaller.installPackageArchived(archivedPackageInfo, params, 2073 new IntentSender((IIntentSender) new IIntentSender.Stub() { 2074 @Override 2075 public void send(int code, Intent intent, String resolvedType, 2076 IBinder whitelistToken, 2077 IIntentReceiver finishedReceiver, 2078 String requiredPermission, Bundle options) 2079 throws RemoteException { 2080 status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 2081 Integer.MIN_VALUE)); 2082 String msg = intent.getStringExtra( 2083 PackageInstaller.EXTRA_STATUS_MESSAGE); 2084 if (TextUtils.isEmpty(msg)) { 2085 msg = String.valueOf(intent.getExtras().get(Intent.EXTRA_INTENT)); 2086 } 2087 statusMessage.complete(msg); 2088 } 2089 })); 2090 assertEquals(statusMessage.get(), expectedStatus, (int) status.get()); 2091 if (expectedResultStartsWith != null) { 2092 assertThat(statusMessage.get()).startsWith(expectedResultStartsWith); 2093 } 2094 }, INSTALL_PACKAGES, Manifest.permission.INTERACT_ACROSS_USERS, 2095 Manifest.permission.INTERACT_ACROSS_USERS_FULL); 2096 } 2097 2098 @Test testInvalidInstallSessionParamsPackageNames()2099 public void testInvalidInstallSessionParamsPackageNames() throws Exception { 2100 var maliciousPayload = """ 2101 @null 2102 2103 victim $UID 1 /data/user/0 default:targetSdkVersion=28 none 0 0 1 @null 2104 """; 2105 2106 var packageInstaller = mContext.getPackageManager().getPackageInstaller(); 2107 SystemUtil.runWithShellPermissionIdentity(mInstrumentation.getUiAutomation(), () -> { 2108 var params1 = new SessionParams(MODE_FULL_INSTALL); 2109 params1.setAppPackageName(maliciousPayload); 2110 params1.setInstallerPackageName(mContext.getPackageName()); 2111 var session1 = packageInstaller.getSessionInfo(packageInstaller.createSession(params1)); 2112 assertThat(session1.getAppPackageName()).isNull(); 2113 assertThat(session1.getInstallerPackageName()).isEqualTo(mContext.getPackageName()); 2114 packageInstaller.openSession(session1.sessionId).abandon(); 2115 2116 var params2 = new SessionParams(MODE_FULL_INSTALL); 2117 params2.setAppPackageName("android.com"); 2118 params2.setInstallerPackageName(maliciousPayload); 2119 var session2 = packageInstaller.getSessionInfo(packageInstaller.createSession(params2)); 2120 assertThat(session2.getAppPackageName()).isEqualTo("android.com"); 2121 assertThat(session2.getInstallerPackageName()).isEqualTo(mContext.getPackageName()); 2122 packageInstaller.openSession(session2.sessionId).abandon(); 2123 }); 2124 } 2125 2126 @Test testGetLaunchIntentSenderForPackage()2127 public void testGetLaunchIntentSenderForPackage() throws Exception { 2128 final Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor( 2129 LauncherMockActivity.class.getName(), null /* result */, false /* block */); 2130 mInstrumentation.addMonitor(monitor); 2131 2132 try { 2133 final IntentSender intentSender = mPackageManager.getLaunchIntentSenderForPackage( 2134 PACKAGE_NAME); 2135 assertThat(intentSender.getCreatorPackage()).isEqualTo(PACKAGE_NAME); 2136 assertThat(intentSender.getCreatorUid()).isEqualTo(mContext.getApplicationInfo().uid); 2137 2138 sendIntent(intentSender); 2139 final Activity activity = monitor.waitForActivityWithTimeout(TIMEOUT_MS); 2140 assertThat(activity).isNotNull(); 2141 activity.finish(); 2142 } finally { 2143 mInstrumentation.removeMonitor(monitor); 2144 } 2145 } 2146 2147 @Test(expected = IntentSender.SendIntentException.class) testGetLaunchIntentSenderForPackage_noMainActivity()2148 public void testGetLaunchIntentSenderForPackage_noMainActivity() throws Exception { 2149 assertThat(installPackage(EMPTY_APP_APK)).isTrue(); 2150 final PackageInfo packageInfo = mPackageManager.getPackageInfo(EMPTY_APP_PACKAGE_NAME, 2151 PackageManager.PackageInfoFlags.of(0)); 2152 assertThat(packageInfo.packageName).isEqualTo(EMPTY_APP_PACKAGE_NAME); 2153 final Intent intent = new Intent(Intent.ACTION_MAIN); 2154 intent.setPackage(EMPTY_APP_PACKAGE_NAME); 2155 assertThat(mPackageManager.queryIntentActivities(intent, 2156 PackageManager.ResolveInfoFlags.of(0))).isEmpty(); 2157 2158 final IntentSender intentSender = mPackageManager.getLaunchIntentSenderForPackage( 2159 EMPTY_APP_PACKAGE_NAME); 2160 assertThat(intentSender.getCreatorPackage()).isEqualTo(PACKAGE_NAME); 2161 assertThat(intentSender.getCreatorUid()).isEqualTo(mContext.getApplicationInfo().uid); 2162 2163 sendIntent(intentSender); 2164 } 2165 2166 @Test(expected = IntentSender.SendIntentException.class) testGetLaunchIntentSenderForPackage_packageNotExist()2167 public void testGetLaunchIntentSenderForPackage_packageNotExist() throws Exception { 2168 try { 2169 mPackageManager.getPackageInfo(EMPTY_APP_PACKAGE_NAME, 2170 PackageManager.PackageInfoFlags.of(0)); 2171 fail(EMPTY_APP_PACKAGE_NAME + " should not exist in the device"); 2172 } catch (NameNotFoundException e) { 2173 } 2174 final IntentSender intentSender = mPackageManager.getLaunchIntentSenderForPackage( 2175 EMPTY_APP_PACKAGE_NAME); 2176 assertThat(intentSender.getCreatorPackage()).isEqualTo(PACKAGE_NAME); 2177 assertThat(intentSender.getCreatorUid()).isEqualTo(mContext.getApplicationInfo().uid); 2178 2179 sendIntent(intentSender); 2180 } 2181 2182 @Test testDefaultHomeActivity_doesntChange_whenInstallAnotherLauncher()2183 public void testDefaultHomeActivity_doesntChange_whenInstallAnotherLauncher() throws Exception { 2184 final Intent homeIntent = new Intent(Intent.ACTION_MAIN) 2185 .addCategory(Intent.CATEGORY_HOME); 2186 final String currentHomeActivity = 2187 mPackageManager.resolveActivity(homeIntent, 2188 PackageManager.ResolveInfoFlags.of(0)).activityInfo.name; 2189 2190 // Install another launcher app. 2191 assertThat(installPackage(MOCK_LAUNCHER_APK)).isTrue(); 2192 2193 // There is an async operation to re-set the default home activity in Role with no way 2194 // to listen for completion once a package installed, so poll until the default home 2195 // activity is set. 2196 PollingCheck.waitFor(() -> currentHomeActivity.equals( 2197 mPackageManager.resolveActivity(homeIntent, 2198 PackageManager.ResolveInfoFlags.of(0)).activityInfo.name)); 2199 final List<String> homeApps = 2200 mPackageManager.queryIntentActivities(homeIntent, 2201 PackageManager.ResolveInfoFlags.of(0)).stream() 2202 .map(i -> i.activityInfo.packageName).collect(Collectors.toList()); 2203 assertThat(homeApps.contains(MOCK_LAUNCHER_PACKAGE_NAME)).isTrue(); 2204 } 2205 2206 @Test setComponentEnabledSetting_nonExistentPackage_withoutPermission()2207 public void setComponentEnabledSetting_nonExistentPackage_withoutPermission() { 2208 final ComponentName componentName = ComponentName.createRelative( 2209 NON_EXISTENT_PACKAGE_NAME, "ClassName"); 2210 assertThrows(SecurityException.class, () -> mPackageManager.setComponentEnabledSetting( 2211 componentName, COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */)); 2212 } 2213 2214 @Test setComponentEnabledSetting_nonExistentPackage_hasPermission()2215 public void setComponentEnabledSetting_nonExistentPackage_hasPermission() { 2216 final ComponentName componentName = ComponentName.createRelative( 2217 NON_EXISTENT_PACKAGE_NAME, "ClassName"); 2218 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 2219 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 2220 2221 try { 2222 assertThrows(IllegalArgumentException.class, 2223 () -> mPackageManager.setComponentEnabledSetting(componentName, 2224 COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */)); 2225 } finally { 2226 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 2227 } 2228 } 2229 2230 @Test loadApplicationLabel_withLongLabelName_truncated()2231 public void loadApplicationLabel_withLongLabelName_truncated() throws Exception { 2232 assertThat(installPackage(LONG_LABEL_NAME_APK)).isTrue(); 2233 final ApplicationInfo info = mPackageManager.getApplicationInfo( 2234 EMPTY_APP_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0)); 2235 final CharSequence resLabel = mPackageManager.getText( 2236 EMPTY_APP_PACKAGE_NAME, info.labelRes, info); 2237 2238 assertThat(resLabel.length()).isGreaterThan(MAX_SAFE_LABEL_LENGTH); 2239 assertThat(info.loadLabel(mPackageManager).length()).isEqualTo(MAX_SAFE_LABEL_LENGTH); 2240 } 2241 2242 @Test loadComponentLabel_withLongLabelName_truncated()2243 public void loadComponentLabel_withLongLabelName_truncated() throws Exception { 2244 assertThat(installPackage(LONG_LABEL_NAME_APK)).isTrue(); 2245 final ComponentName componentName = ComponentName.createRelative( 2246 EMPTY_APP_PACKAGE_NAME, ".MockActivity"); 2247 final ApplicationInfo appInfo = mPackageManager.getApplicationInfo( 2248 EMPTY_APP_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0)); 2249 final ActivityInfo activityInfo = mPackageManager.getActivityInfo( 2250 componentName, PackageManager.ComponentInfoFlags.of(0)); 2251 final CharSequence resLabel = mPackageManager.getText( 2252 EMPTY_APP_PACKAGE_NAME, activityInfo.labelRes, appInfo); 2253 2254 assertThat(resLabel.length()).isGreaterThan(MAX_SAFE_LABEL_LENGTH); 2255 assertThat(activityInfo.loadLabel(mPackageManager).length()) 2256 .isEqualTo(MAX_SAFE_LABEL_LENGTH); 2257 } 2258 2259 @Test setComponentEnabledSettings_withDuplicatedComponent()2260 public void setComponentEnabledSettings_withDuplicatedComponent() { 2261 final List<ComponentEnabledSetting> enabledSettings = List.of( 2262 new ComponentEnabledSetting( 2263 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2264 new ComponentEnabledSetting( 2265 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP)); 2266 2267 assertThrows(IllegalArgumentException.class, 2268 () -> mPackageManager.setComponentEnabledSettings(enabledSettings)); 2269 } 2270 2271 @Test setComponentEnabledSettings_flagDontKillAppConflict()2272 public void setComponentEnabledSettings_flagDontKillAppConflict() { 2273 final List<ComponentEnabledSetting> enabledSettings = List.of( 2274 new ComponentEnabledSetting( 2275 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2276 new ComponentEnabledSetting( 2277 SERVICE_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, 0)); 2278 2279 assertThrows(IllegalArgumentException.class, 2280 () -> mPackageManager.setComponentEnabledSettings(enabledSettings)); 2281 } 2282 2283 @Test setComponentEnabledSettings_disableSelfAndStubApp_withoutPermission()2284 public void setComponentEnabledSettings_disableSelfAndStubApp_withoutPermission() { 2285 final List<ComponentEnabledSetting> enabledSettings = List.of( 2286 new ComponentEnabledSetting( 2287 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2288 new ComponentEnabledSetting( 2289 STUB_ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, 0)); 2290 2291 assertThrows(SecurityException.class, 2292 () -> mPackageManager.setComponentEnabledSettings(enabledSettings)); 2293 } 2294 2295 @Test setComponentEnabledSettings_disableSelf()2296 public void setComponentEnabledSettings_disableSelf() throws Exception { 2297 final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT); 2298 final int serviceState = mPackageManager.getComponentEnabledSetting(SERVICE_COMPONENT); 2299 assertThat(activityState).isAnyOf( 2300 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED); 2301 assertThat(serviceState).isAnyOf( 2302 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED); 2303 2304 try { 2305 final List<ComponentEnabledSetting> enabledSettings = List.of( 2306 new ComponentEnabledSetting( 2307 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2308 new ComponentEnabledSetting( 2309 SERVICE_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP)); 2310 setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings); 2311 } finally { 2312 final List<ComponentEnabledSetting> enabledSettings = List.of( 2313 new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP), 2314 new ComponentEnabledSetting(SERVICE_COMPONENT, serviceState, DONT_KILL_APP)); 2315 setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings); 2316 } 2317 } 2318 2319 @Test setComponentEnabledSettings_disableSelfAndStubApp_killStubApp()2320 public void setComponentEnabledSettings_disableSelfAndStubApp_killStubApp() 2321 throws Exception { 2322 final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT); 2323 final int stubState = mPackageManager.getComponentEnabledSetting(STUB_ACTIVITY_COMPONENT); 2324 assertThat(activityState).isAnyOf( 2325 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED); 2326 assertThat(stubState).isAnyOf( 2327 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED); 2328 2329 final Intent intent = new Intent(); 2330 intent.setComponent(STUB_SERVICE_COMPONENT); 2331 final AtomicBoolean killed = new AtomicBoolean(); 2332 mServiceTestRule.bindService(intent, new ServiceConnection() { 2333 @Override 2334 public void onServiceConnected(ComponentName name, IBinder service) { 2335 } 2336 2337 @Override 2338 public void onServiceDisconnected(ComponentName name) { 2339 killed.set(true); 2340 } 2341 }, Context.BIND_AUTO_CREATE); 2342 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 2343 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 2344 2345 try { 2346 final List<ComponentEnabledSetting> enabledSettings = List.of( 2347 new ComponentEnabledSetting( 2348 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2349 new ComponentEnabledSetting( 2350 STUB_ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, 0)); 2351 setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings); 2352 TestUtils.waitUntil("Waiting for the process " + STUB_PACKAGE_NAME 2353 + " to die", () -> killed.get()); 2354 } finally { 2355 final List<ComponentEnabledSetting> enabledSettings = List.of( 2356 new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP), 2357 new ComponentEnabledSetting(STUB_ACTIVITY_COMPONENT, stubState, 0)); 2358 setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings); 2359 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 2360 } 2361 } 2362 2363 @Test setComponentEnabledSettings_noStateChanged_noBroadcastReceived()2364 public void setComponentEnabledSettings_noStateChanged_noBroadcastReceived() { 2365 final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT); 2366 final int serviceState = mPackageManager.getComponentEnabledSetting(SERVICE_COMPONENT); 2367 final List<ComponentEnabledSetting> enabledSettings = List.of( 2368 new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP), 2369 new ComponentEnabledSetting(SERVICE_COMPONENT, serviceState, DONT_KILL_APP)); 2370 2371 assertThrows(TimeoutException.class, 2372 () -> setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings)); 2373 } 2374 2375 @Test setComponentEnabledSetting_disableMultiplePackagesNoKill()2376 public void setComponentEnabledSetting_disableMultiplePackagesNoKill() throws Exception { 2377 final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT); 2378 final int serviceState = mPackageManager.getComponentEnabledSetting(SERVICE_COMPONENT); 2379 assertThat(installPackage(MOCK_LAUNCHER_APK)).isTrue(); 2380 final List<ComponentEnabledSetting> settings = List.of( 2381 new ComponentEnabledSetting(RESET_ENABLED_SETTING_ACTIVITY_COMPONENT, 2382 COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2383 new ComponentEnabledSetting(RESET_ENABLED_SETTING_RECEIVER_COMPONENT, 2384 COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2385 new ComponentEnabledSetting(RESET_ENABLED_SETTING_SERVICE_COMPONENT, 2386 COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2387 new ComponentEnabledSetting(RESET_ENABLED_SETTING_PROVIDER_COMPONENT, 2388 COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2389 new ComponentEnabledSetting( 2390 ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP), 2391 new ComponentEnabledSetting( 2392 SERVICE_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP)); 2393 2394 try { 2395 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 2396 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 2397 setComponentEnabledSettingsAndWaitForBroadcasts(settings); 2398 } finally { 2399 final List<ComponentEnabledSetting> enabledSettings = List.of( 2400 new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP), 2401 new ComponentEnabledSetting(SERVICE_COMPONENT, serviceState, DONT_KILL_APP)); 2402 setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings); 2403 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 2404 } 2405 } 2406 2407 @Test 2408 @RequiresFlagsEnabled(FLAG_IMPROVE_HOME_APP_BEHAVIOR) testEnableAndResetComponentSetting_pressHomeButton_notShowResolverActivity()2409 public void testEnableAndResetComponentSetting_pressHomeButton_notShowResolverActivity() 2410 throws Exception { 2411 final ComponentName componentName = new ComponentName(PACKAGE_NAME, 2412 "android.content.pm.cts.FakeLauncherActivity"); 2413 final String resolverActivity = getResolverActivity(); 2414 2415 try { 2416 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 2417 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 2418 setComponentEnabledSettingsAndWaitForBroadcasts( 2419 List.of(new ComponentEnabledSetting(componentName, 2420 COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP))); 2421 2422 // Press home button to trigger the resolver activity dialog to select the default home. 2423 mUiDevice.pressHome(); 2424 2425 // The resolver activity shouldn't be shown. 2426 assertThrows(AssertionFailedError.class, 2427 () -> TestUtils.waitUntil( 2428 "Waiting for the resolver activity to be shown.", 2429 5 /* timeoutSecond */, () -> hasResolverActivity(resolverActivity))); 2430 } finally { 2431 setComponentEnabledSettingsAndWaitForBroadcasts( 2432 List.of(new ComponentEnabledSetting(componentName, 2433 COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP))); 2434 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 2435 } 2436 2437 // Press home button to trigger the resolver activity dialog to select the default home. 2438 mUiDevice.pressHome(); 2439 2440 // The resolver activity shouldn't be shown. 2441 assertThrows(AssertionFailedError.class, 2442 () -> TestUtils.waitUntil( 2443 "Waiting for the resolver activity to be shown.", 2444 5 /* timeoutSecond */, () -> hasResolverActivity(resolverActivity))); 2445 } 2446 getResolverActivity()2447 private String getResolverActivity() { 2448 int resId = Resources.getSystem().getIdentifier( 2449 "config_customResolverActivity", "string", "android"); 2450 String customResolverActivity = mContext.getString(resId); 2451 Log.d(TAG, "getResolverActivity customResolverActivity=" + customResolverActivity); 2452 if (TextUtils.isEmpty(customResolverActivity)) { 2453 // If custom resolver activity is not in use, it will use the Android default. 2454 return "android/com.android.internal.app.ResolverActivity"; 2455 } 2456 return customResolverActivity; 2457 } 2458 hasResolverActivity(String resolverActivity)2459 private boolean hasResolverActivity(String resolverActivity) throws Exception { 2460 String commandOutput = mUiDevice.executeShellCommand("dumpsys activity activities"); 2461 final String[] lines = commandOutput.split("\\n", -1); 2462 2463 if (lines == null) { 2464 return false; 2465 } 2466 2467 for (int i = 0; i < lines.length; i++) { 2468 final String line = lines[i]; 2469 if (line.contains("Resumed:") && line.contains(resolverActivity)) { 2470 Log.d(TAG, "hasResolverActivity find line=" + line); 2471 return true; 2472 } 2473 } 2474 return false; 2475 } 2476 2477 @Test clearApplicationUserData_resetComponentEnabledSettings()2478 public void clearApplicationUserData_resetComponentEnabledSettings() throws Exception { 2479 assertThat(installPackage(MOCK_LAUNCHER_APK)).isTrue(); 2480 final List<ComponentEnabledSetting> settings = List.of( 2481 new ComponentEnabledSetting(RESET_ENABLED_SETTING_ACTIVITY_COMPONENT, 2482 COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */), 2483 new ComponentEnabledSetting(RESET_ENABLED_SETTING_RECEIVER_COMPONENT, 2484 COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */), 2485 new ComponentEnabledSetting(RESET_ENABLED_SETTING_SERVICE_COMPONENT, 2486 COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */), 2487 new ComponentEnabledSetting(RESET_ENABLED_SETTING_PROVIDER_COMPONENT, 2488 COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */)); 2489 2490 try { 2491 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 2492 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 2493 // update component enabled settings 2494 setComponentEnabledSettingsAndWaitForBroadcasts(settings); 2495 2496 clearApplicationUserData(MOCK_LAUNCHER_PACKAGE_NAME); 2497 2498 assertThat(mPackageManager 2499 .getComponentEnabledSetting(RESET_ENABLED_SETTING_ACTIVITY_COMPONENT)) 2500 .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT); 2501 assertThat(mPackageManager 2502 .getComponentEnabledSetting(RESET_ENABLED_SETTING_RECEIVER_COMPONENT)) 2503 .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT); 2504 assertThat(mPackageManager 2505 .getComponentEnabledSetting(RESET_ENABLED_SETTING_SERVICE_COMPONENT)) 2506 .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT); 2507 assertThat(mPackageManager 2508 .getComponentEnabledSetting(RESET_ENABLED_SETTING_PROVIDER_COMPONENT)) 2509 .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT); 2510 } finally { 2511 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 2512 } 2513 } 2514 setComponentEnabledSettingsAndWaitForBroadcasts( List<ComponentEnabledSetting> enabledSettings)2515 private void setComponentEnabledSettingsAndWaitForBroadcasts( 2516 List<ComponentEnabledSetting> enabledSettings) 2517 throws InterruptedException, TimeoutException { 2518 final List<ComponentName> componentsToWait = enabledSettings.stream() 2519 .map(enabledSetting -> enabledSetting.getComponentName()) 2520 .collect(Collectors.toList()); 2521 final IntentFilter filter = new IntentFilter(); 2522 filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 2523 filter.addDataScheme("package"); 2524 final CountDownLatch latch = new CountDownLatch(1 /* count */); 2525 final BroadcastReceiver br = new BroadcastReceiver() { 2526 @Override 2527 public void onReceive(Context context, Intent intent) { 2528 final String packageName = intent.getData() != null 2529 ? intent.getData().getSchemeSpecificPart() : null; 2530 final String[] receivedComponents = intent.getStringArrayExtra( 2531 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); 2532 if (packageName == null || receivedComponents == null) { 2533 return; 2534 } 2535 for (String componentString : receivedComponents) { 2536 componentsToWait.remove(new ComponentName(packageName, componentString)); 2537 } 2538 if (componentsToWait.isEmpty()) { 2539 latch.countDown(); 2540 } 2541 } 2542 }; 2543 mContext.registerReceiver(br, filter, RECEIVER_EXPORTED); 2544 try { 2545 mPackageManager.setComponentEnabledSettings(enabledSettings); 2546 if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 2547 throw new TimeoutException("Package changed broadcasts for " + componentsToWait 2548 + " not received in " + TIMEOUT_MS + "ms"); 2549 } 2550 for (ComponentEnabledSetting enabledSetting : enabledSettings) { 2551 assertThat(mPackageManager.getComponentEnabledSetting( 2552 enabledSetting.getComponentName())) 2553 .isEqualTo(enabledSetting.getEnabledState()); 2554 } 2555 } finally { 2556 mContext.unregisterReceiver(br); 2557 } 2558 } 2559 clearApplicationUserData(String packageName)2560 private void clearApplicationUserData(String packageName) { 2561 final StringBuilder cmd = new StringBuilder("pm clear --user "); 2562 cmd.append(UserHandle.myUserId()).append(" "); 2563 cmd.append(packageName); 2564 SystemUtil.runShellCommand(cmd.toString()); 2565 } 2566 2567 @Test testPrebuiltSharedLibraries_existOnDevice()2568 public void testPrebuiltSharedLibraries_existOnDevice() { 2569 final List<SharedLibraryInfo> infos = 2570 mPackageManager.getSharedLibraries(PackageManager.PackageInfoFlags.of(0)).stream() 2571 .filter(info -> info.isBuiltin() && !info.isNative()) 2572 .collect(Collectors.toList()); 2573 assertThat(infos).isNotEmpty(); 2574 2575 final List<SharedLibraryInfo> fileNotExistInfos = infos.stream() 2576 .filter(info -> !(new File(info.getPath()).exists())).collect( 2577 Collectors.toList()); 2578 assertThat(fileNotExistInfos).isEmpty(); 2579 } 2580 2581 @Test testInstallUpdate_applicationIsKilled()2582 public void testInstallUpdate_applicationIsKilled() throws Exception { 2583 final Intent intent = new Intent(); 2584 intent.setComponent(STUB_SERVICE_COMPONENT); 2585 final AtomicBoolean killed = new AtomicBoolean(); 2586 mServiceTestRule.bindService(intent, new ServiceConnection() { 2587 @Override 2588 public void onServiceConnected(ComponentName name, IBinder service) { 2589 } 2590 2591 @Override 2592 public void onServiceDisconnected(ComponentName name) { 2593 killed.set(true); 2594 } 2595 }, Context.BIND_AUTO_CREATE); 2596 2597 installPackage(STUB_PACKAGE_APK); 2598 // The application should be killed after updating. 2599 TestUtils.waitUntil("Waiting for the process " + STUB_PACKAGE_NAME + " to die", 2600 10 /* timeoutSecond */, () -> killed.get()); 2601 } 2602 2603 @Test testInstallUpdate_dontKill_applicationIsNotKilled()2604 public void testInstallUpdate_dontKill_applicationIsNotKilled() throws Exception { 2605 installPackage(STUB_PACKAGE_APK); 2606 2607 final Intent intent = new Intent(); 2608 intent.setComponent(STUB_SERVICE_COMPONENT); 2609 final AtomicBoolean killed = new AtomicBoolean(); 2610 mServiceTestRule.bindService(intent, new ServiceConnection() { 2611 @Override 2612 public void onServiceConnected(ComponentName name, IBinder service) { 2613 } 2614 2615 @Override 2616 public void onServiceDisconnected(ComponentName name) { 2617 killed.set(true); 2618 } 2619 }, Context.BIND_AUTO_CREATE); 2620 2621 addSplitDontKill(STUB_PACKAGE_NAME, STUB_PACKAGE_SPLIT); 2622 // The application shouldn't be killed after updating with --dont-kill. 2623 assertThrows(AssertionFailedError.class, 2624 () -> TestUtils.waitUntil( 2625 "Waiting for the process " + STUB_PACKAGE_NAME + " to die", 2626 10 /* timeoutSecond */, () -> killed.get())); 2627 } 2628 2629 @Test testPackageInfoFlags()2630 public void testPackageInfoFlags() { 2631 final long rawFlags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS 2632 | PackageManager.GET_CONFIGURATIONS; 2633 assertEquals(rawFlags, PackageManager.PackageInfoFlags.of(rawFlags).getValue()); 2634 } 2635 2636 @Test testApplicationInfoFlags()2637 public void testApplicationInfoFlags() { 2638 final long rawFlags = PackageManager.GET_SHARED_LIBRARY_FILES 2639 | PackageManager.MATCH_UNINSTALLED_PACKAGES; 2640 assertEquals(rawFlags, PackageManager.ApplicationInfoFlags.of(rawFlags).getValue()); 2641 } 2642 2643 @Test testResolveInfoFlags()2644 public void testResolveInfoFlags() { 2645 final long rawFlags = PackageManager.MATCH_DIRECT_BOOT_AWARE 2646 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 2647 | PackageManager.MATCH_SYSTEM_ONLY; 2648 assertEquals(rawFlags, PackageManager.ResolveInfoFlags.of(rawFlags).getValue()); 2649 } 2650 2651 @Test testComponentInfoFlags()2652 public void testComponentInfoFlags() { 2653 final long rawFlags = PackageManager.GET_META_DATA; 2654 assertEquals(rawFlags, PackageManager.ComponentInfoFlags.of(rawFlags).getValue()); 2655 } 2656 2657 @Test testDeleteDexopt_withoutShellIdentity()2658 public void testDeleteDexopt_withoutShellIdentity() throws Exception { 2659 assertThat(runCommand("pm delete-dexopt " + PACKAGE_NAME)) 2660 .contains(SecurityException.class.getName()); 2661 } 2662 2663 @Test testSettingAndReserveCopyVerityProtected()2664 public void testSettingAndReserveCopyVerityProtected() throws Exception { 2665 File systemDir = new File(Environment.getDataDirectory(), "system"); 2666 File settings = new File(systemDir, "packages.xml"); 2667 File settingsReserveCopy = new File(systemDir, "packages.xml.reservecopy"); 2668 2669 // Primary. 2670 assertTrue(settings.exists()); 2671 // Reserve copy. 2672 assertTrue(settingsReserveCopy.exists()); 2673 // Temporary backup. 2674 assertFalse(new File(systemDir, "packages-backup.xml").exists()); 2675 2676 assumeTrue(VerityUtils.isFsVeritySupported()); 2677 assertTrue(VerityUtils.hasFsverity(settings.getAbsolutePath())); 2678 assertTrue(VerityUtils.hasFsverity(settingsReserveCopy.getAbsolutePath())); 2679 } 2680 runCommand(String cmd)2681 private static String runCommand(String cmd) throws Exception { 2682 final var process = Runtime.getRuntime().exec(cmd); 2683 final StringBuilder output = new StringBuilder(); 2684 BufferedReader reader = 2685 new BufferedReader(new InputStreamReader(process.getInputStream())); 2686 reader.lines().forEach(line -> output.append(line)); 2687 reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); 2688 reader.lines().forEach(line -> output.append(line)); 2689 process.waitFor(); 2690 return output.toString(); 2691 } 2692 2693 @Test testNewAppInstalledNotificationEnabled()2694 public void testNewAppInstalledNotificationEnabled() { 2695 SystemUtil.runWithShellPermissionIdentity(mInstrumentation.getUiAutomation(), () -> { 2696 Settings.Global.putString(mContext.getContentResolver(), 2697 Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED, "1" /* true */); 2698 }, WRITE_SECURE_SETTINGS); 2699 2700 assertEquals(true, mPackageManager.shouldShowNewAppInstalledNotification()); 2701 2702 } 2703 2704 @Test testCanUserUninstall_setToTrue_returnsTrue()2705 public void testCanUserUninstall_setToTrue_returnsTrue() throws RemoteException { 2706 SystemUtil.runWithShellPermissionIdentity(mInstrumentation.getUiAutomation(), () -> { 2707 IPackageManager iPm = ActivityThread.getPackageManager(); 2708 iPm.setBlockUninstallForUser(PACKAGE_NAME, true, USER_CURRENT); 2709 }, DELETE_PACKAGES); 2710 2711 assertEquals(true, mPackageManager.canUserUninstall(PACKAGE_NAME, CURRENT)); 2712 } 2713 2714 @Test testAppWithNoAppStorageUpdateSuccess()2715 public void testAppWithNoAppStorageUpdateSuccess() throws Exception { 2716 installPackage(TEST_HW_NO_APP_STORAGE); 2717 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 2718 // Updates that don't change value of NO_APP_DATA_STORAGE property are allowed. 2719 installPackage(TEST_HW_NO_APP_STORAGE); 2720 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 2721 } 2722 2723 @Test testAppUpdateAddsNoAppDataStorageProperty()2724 public void testAppUpdateAddsNoAppDataStorageProperty() throws Exception { 2725 installPackage(HELLO_WORLD_APK); 2726 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 2727 installPackage( 2728 TEST_HW_NO_APP_STORAGE, 2729 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Update " 2730 + "attempted to change value of " 2731 + "android.internal.PROPERTY_NO_APP_DATA_STORAGE"); 2732 } 2733 2734 @Test testAppUpdateRemovesNoAppDataStorageProperty()2735 public void testAppUpdateRemovesNoAppDataStorageProperty() throws Exception { 2736 installPackage(TEST_HW_NO_APP_STORAGE); 2737 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 2738 installPackage( 2739 HELLO_WORLD_APK, 2740 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Update " 2741 + "attempted to change value of " 2742 + "android.internal.PROPERTY_NO_APP_DATA_STORAGE"); 2743 } 2744 2745 @Test testNoAppDataStoragePropertyCanChangeAfterUninstall()2746 public void testNoAppDataStoragePropertyCanChangeAfterUninstall() throws Exception { 2747 installPackage(TEST_HW_NO_APP_STORAGE); 2748 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 2749 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2750 // After app is uninstalled new install can change the value of the property. 2751 installPackage(HELLO_WORLD_APK); 2752 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 2753 } 2754 2755 @Test testQuerySdkSandboxPackageName()2756 public void testQuerySdkSandboxPackageName() throws Exception { 2757 final PackageManager pm = mPackageManager; 2758 final String name = pm.getSdkSandboxPackageName(); 2759 assertNotNull(name); 2760 final ApplicationInfo info = pm.getApplicationInfo( 2761 name, PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY)); 2762 assertEquals(ApplicationInfo.FLAG_SYSTEM, info.flags & ApplicationInfo.FLAG_SYSTEM); 2763 assertTrue(info.sourceDir.startsWith("/apex/com.android.adservices")); 2764 } 2765 2766 @Test testGetPackagesForUid_sdkSandboxUid()2767 public void testGetPackagesForUid_sdkSandboxUid() throws Exception { 2768 final PackageManager pm = mPackageManager; 2769 final String[] pkgs = pm.getPackagesForUid(Process.toSdkSandboxUid(10239)); 2770 assertEquals(1, pkgs.length); 2771 assertEquals(pm.getSdkSandboxPackageName(), pkgs[0]); 2772 } 2773 2774 @Test testGetNameForUid_sdkSandboxUid()2775 public void testGetNameForUid_sdkSandboxUid() throws Exception { 2776 final PackageManager pm = mPackageManager; 2777 final String pkgName = pm.getNameForUid(Process.toSdkSandboxUid(11543)); 2778 assertEquals(pm.getSdkSandboxPackageName(), pkgName); 2779 } 2780 2781 @Test testGetNamesForUids_sdkSandboxUids()2782 public void testGetNamesForUids_sdkSandboxUids() throws Exception { 2783 final PackageManager pm = mPackageManager; 2784 final int[] uids = new int[]{Process.toSdkSandboxUid(10101)}; 2785 final String[] names = pm.getNamesForUids(uids); 2786 assertEquals(1, names.length); 2787 assertEquals(pm.getSdkSandboxPackageName(), names[0]); 2788 } 2789 2790 @Test testShellInitiatingPkgName()2791 public void testShellInitiatingPkgName() throws Exception { 2792 installPackage(HELLO_WORLD_APK); 2793 InstallSourceInfo installSourceInfo = mPackageManager 2794 .getInstallSourceInfo(HELLO_WORLD_PACKAGE_NAME); 2795 assertEquals(SHELL_PACKAGE_NAME, installSourceInfo.getInitiatingPackageName()); 2796 assertNull(installSourceInfo.getInstallingPackageName()); 2797 } 2798 2799 @Test testShellInitiatingPkgNameSetInstallerPkgName()2800 public void testShellInitiatingPkgNameSetInstallerPkgName() throws Exception { 2801 installPackageWithInstallerPkgName(HELLO_WORLD_APK, PACKAGE_NAME); 2802 InstallSourceInfo installSourceInfo = mPackageManager 2803 .getInstallSourceInfo(HELLO_WORLD_PACKAGE_NAME); 2804 assertEquals(SHELL_PACKAGE_NAME, installSourceInfo.getInitiatingPackageName()); 2805 assertEquals(PACKAGE_NAME, installSourceInfo.getInstallingPackageName()); 2806 } 2807 2808 @Test testUninstall()2809 public void testUninstall() throws Exception { 2810 final int userId = mContext.getUserId(); 2811 installPackage(HELLO_WORLD_APK); 2812 // Test that the installed state is true in the dumpsys 2813 assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("true"); 2814 // Queryable without special flags 2815 mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2816 PackageManager.PackageInfoFlags.of(0)); 2817 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2818 assertThat(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)).isFalse(); 2819 // Not queryable even MATCH_KNOWN_PACKAGES 2820 assertThrows(NameNotFoundException.class, 2821 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2822 PackageManager.PackageInfoFlags.of(MATCH_KNOWN_PACKAGES))); 2823 // No installed state in dumpsys 2824 assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isNull(); 2825 } 2826 2827 @Test testUninstallWithKeepData()2828 public void testUninstallWithKeepData() throws Exception { 2829 final int userId = mContext.getUserId(); 2830 installPackage(HELLO_WORLD_APK); 2831 // Test that the installed state is true in the dumpsys 2832 assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("true"); 2833 PackageInfo packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2834 PackageManager.PackageInfoFlags.of(0)); 2835 final String oldDataDir = packageInfo.applicationInfo.dataDir; 2836 final long firstInstallTime = packageInfo.firstInstallTime; 2837 // Launch activity to write data to the data dir and verify the stats 2838 launchMainActivity(HELLO_WORLD_PACKAGE_NAME); 2839 StorageStatsManager storageStatsManager = 2840 mContext.getSystemService(StorageStatsManager.class); 2841 StorageStats stats = storageStatsManager.queryStatsForPackage( 2842 packageInfo.applicationInfo.storageUuid, HELLO_WORLD_PACKAGE_NAME, 2843 UserHandle.of(userId)); 2844 assertThat(stats.getDataBytes()).isGreaterThan(0L); 2845 2846 uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME); 2847 assertThat(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)).isFalse(); 2848 2849 // Queryable with MATCH_UNINSTALLED_PACKAGES and MATCH_KNOWN_PACKAGES flags 2850 expectThrows(NameNotFoundException.class, 2851 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2852 PackageManager.PackageInfoFlags.of(0))); 2853 expectThrows(NameNotFoundException.class, 2854 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2855 PackageManager.PackageInfoFlags.of(MATCH_ANY_USER))); 2856 mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2857 PackageManager.PackageInfoFlags.of(MATCH_KNOWN_PACKAGES)); 2858 packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2859 PackageManager.PackageInfoFlags.of(MATCH_UNINSTALLED_PACKAGES | GET_SIGNATURES)); 2860 assertThat(packageInfo.packageName).isEqualTo(HELLO_WORLD_PACKAGE_NAME); 2861 // Test that the code path is gone but the signing info is still available 2862 assertThat(packageInfo.applicationInfo.getCodePath()).isNull(); 2863 assertThat(packageInfo.signingInfo).isNotNull(); 2864 assertThat(packageInfo.applicationInfo.targetSdkVersion).isGreaterThan(0); 2865 assertThat(packageInfo.signatures).isNotNull(); 2866 assertThat(packageInfo.firstInstallTime).isEqualTo(firstInstallTime); 2867 // Test that the app's data directory is preserved and matches dumpsys 2868 final String newDataDir = packageInfo.applicationInfo.dataDir; 2869 assertThat(newDataDir).isNotEmpty(); 2870 assertThat(newDataDir).isEqualTo(oldDataDir); 2871 final String appDirInDump = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 2872 " dataDir=/data/user/" + userId); 2873 assertThat("/data/user/" + userId + appDirInDump).isEqualTo(newDataDir); 2874 assertThat(packageInfo.applicationInfo.storageUuid).isNotNull(); 2875 // Test that the installed state is false in the dumpsys 2876 assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("false"); 2877 // Verify the stats 2878 stats = storageStatsManager.queryStatsForPackage( 2879 packageInfo.applicationInfo.storageUuid, HELLO_WORLD_PACKAGE_NAME, 2880 UserHandle.of(UserHandle.myUserId())); 2881 assertThat(stats.getDataBytes()).isGreaterThan(0L); 2882 // Re-install the app and verify that the data dir is the same as before 2883 installPackage(HELLO_WORLD_APK); 2884 assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("true"); 2885 packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2886 PackageManager.PackageInfoFlags.of(0)); 2887 assertThat(packageInfo.applicationInfo.dataDir).isEqualTo(oldDataDir); 2888 // Fully clean up and test that the query fails 2889 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2890 assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isNull(); 2891 expectThrows(NameNotFoundException.class, 2892 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2893 PackageManager.PackageInfoFlags.of(MATCH_UNINSTALLED_PACKAGES))); 2894 } 2895 assertDataAppExists(String packageName)2896 private void assertDataAppExists(String packageName) throws Exception { 2897 var packageInfo = mPackageManager.getPackageInfo(packageName, MATCH_KNOWN_PACKAGES); 2898 assertThat(packageInfo.applicationInfo.dataDir).isNotNull(); 2899 } 2900 2901 @Test testInstallArchivedFromArchived()2902 public void testInstallArchivedFromArchived() throws Exception { 2903 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2904 2905 assertEquals("Success\n", SystemUtil.runShellCommand( 2906 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(), 2907 HELLO_WORLD_APK))); 2908 assertThat(SystemUtil.runShellCommand( 2909 String.format("pm archive %s", HELLO_WORLD_PACKAGE_NAME))).isEqualTo("Success\n"); 2910 // Check "installed" flag. 2911 var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2912 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo; 2913 assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0); 2914 // Check archive state. 2915 assertTrue(applicationInfo.isArchived); 2916 // Not pending restore. 2917 String pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 2918 " pendingRestore="); 2919 assertThat(pendingRestore).isNull(); 2920 2921 byte[] archivedPackage = SystemUtil.runShellCommandByteOutput( 2922 mInstrumentation.getUiAutomation(), 2923 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME); 2924 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2925 2926 // Install archived APK. 2927 assertEquals("Success\n", executeShellCommand( 2928 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(), 2929 archivedPackage.length), archivedPackage)); 2930 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 2931 // Check "installed" flag once again. 2932 applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2933 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo; 2934 assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0); 2935 // Check archive state once again. 2936 assertTrue(applicationInfo.isArchived); 2937 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2938 2939 // Try to install archived without installer. 2940 assertThat(executeShellCommand( 2941 String.format("pm install-archived -t -S %s", archivedPackage.length), 2942 archivedPackage)).startsWith("Failure [INSTALL_FAILED_SESSION_INVALID: Installer"); 2943 } 2944 2945 @Test testInstallArchivedFromArchivedWithUser()2946 public void testInstallArchivedFromArchivedWithUser() throws Exception { 2947 final int userId = mContext.getUserId(); 2948 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2949 2950 assertEquals("Success\n", SystemUtil.runShellCommand( 2951 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(), 2952 HELLO_WORLD_APK))); 2953 assertThat(SystemUtil.runShellCommand( 2954 String.format("pm archive --user %s %s", userId, HELLO_WORLD_PACKAGE_NAME)) 2955 ).isEqualTo("Success\n"); 2956 // Check "installed" flag. 2957 var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2958 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo; 2959 assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0); 2960 // Check archive state. 2961 assertTrue(applicationInfo.isArchived); 2962 2963 if (userId != UserHandle.USER_SYSTEM) { 2964 applicationInfo = mPackageManager.getPackageInfoAsUser(HELLO_WORLD_PACKAGE_NAME, 2965 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES), 2966 UserHandle.USER_SYSTEM).applicationInfo; 2967 // Installed and not archived for the other user. 2968 assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 2969 ApplicationInfo.FLAG_INSTALLED); 2970 assertFalse(applicationInfo.isArchived); 2971 } 2972 2973 byte[] archivedPackage = SystemUtil.runShellCommandByteOutput( 2974 mInstrumentation.getUiAutomation(), 2975 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME); 2976 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 2977 2978 // Install archived APK. 2979 assertEquals("Success\n", executeShellCommand( 2980 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(), 2981 archivedPackage.length), archivedPackage)); 2982 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 2983 // Check "installed" flag once again. 2984 applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 2985 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo; 2986 assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0); 2987 // Check archive state once again. 2988 assertTrue(applicationInfo.isArchived); 2989 } 2990 2991 2992 @Test testInstallArchivedUpdate()2993 public void testInstallArchivedUpdate() throws Exception { 2994 installPackage(HELLO_WORLD_APK); 2995 byte[] archivedPackage = SystemUtil.runShellCommandByteOutput( 2996 mInstrumentation.getUiAutomation(), 2997 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME); 2998 2999 // Try to install archived on top of fully installed app. 3000 assertThat(executeShellCommand( 3001 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(), 3002 archivedPackage.length), archivedPackage)).startsWith( 3003 "Failure [INSTALL_FAILED_SESSION_INVALID: Archived"); 3004 3005 // Uninstall and retry. 3006 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3007 assertEquals("Success\n", executeShellCommand( 3008 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(), 3009 archivedPackage.length), archivedPackage)); 3010 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3011 // Pending restore. 3012 String pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3013 " pendingRestore="); 3014 assertThat(pendingRestore).isEqualTo("true"); 3015 assertDataAppExists(HELLO_WORLD_PACKAGE_NAME); 3016 // Wrong signature. 3017 assertThat(SystemUtil.runShellCommand( 3018 "pm install -t -g " + HELLO_WORLD_DIFF_SIGNER_APK)).startsWith( 3019 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE"); 3020 // Update fails because we can't derive an existing APK. 3021 assertThat(SystemUtil.runShellCommand( 3022 "pm install -t -p " + HELLO_WORLD_PACKAGE_NAME + " -g " 3023 + HELLO_WORLD_UPDATED_APK)).startsWith( 3024 "Failure [INSTALL_FAILED_INVALID_APK: Missing existing base package"); 3025 // Unarchive/full install succeeds. 3026 assertEquals("Success\n", SystemUtil.runShellCommand( 3027 "pm install -t -g " + HELLO_WORLD_UPDATED_APK)); 3028 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 3029 // pendingRestore flag will only be unset if the restore is successfully performed. 3030 // On devices that don't support backup & restore, the following checks will be skipped. 3031 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP)) { 3032 // Not pending restore. 3033 pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3034 " pendingRestore="); 3035 assertThat(pendingRestore).isNull(); 3036 // Uninstall, keep data. 3037 assertEquals("Success\n", 3038 SystemUtil.runShellCommand("pm uninstall -k " + HELLO_WORLD_PACKAGE_NAME)); 3039 // Not pending restore. 3040 pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3041 " pendingRestore="); 3042 assertThat(pendingRestore).isNull(); 3043 } 3044 // Full uninstall. 3045 assertEquals("Success\n", 3046 SystemUtil.runShellCommand("pm uninstall " + HELLO_WORLD_PACKAGE_NAME)); 3047 assertFalse(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3048 } 3049 3050 @Test testInstallArchivedCheckFlags()3051 public void testInstallArchivedCheckFlags() throws Exception { 3052 installPackage(HELLO_WORLD_APK); 3053 byte[] archivedPackage = SystemUtil.runShellCommandByteOutput( 3054 mInstrumentation.getUiAutomation(), 3055 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME); 3056 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3057 3058 // Install a default APK. 3059 assertEquals("Success\n", executeShellCommand( 3060 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(), 3061 archivedPackage.length), archivedPackage)); 3062 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3063 String pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, " pkgFlags=["); 3064 assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA"); 3065 assertThat(pkgFlags).contains("ALLOW_BACKUP"); 3066 String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3067 " privatePkgFlags=["); 3068 assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE"); 3069 assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA"); 3070 String pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3071 " pendingRestore="); 3072 assertThat(pendingRestore).isEqualTo("true"); 3073 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3074 3075 installPackage(HELLO_WORLD_FLAGS_APK); 3076 byte[] archivedPackageFlags = SystemUtil.runShellCommandByteOutput( 3077 mInstrumentation.getUiAutomation(), 3078 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME); 3079 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3080 3081 // Install an APK with non default flags. 3082 assertEquals("Success\n", executeShellCommand( 3083 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(), 3084 archivedPackageFlags.length), archivedPackageFlags)); 3085 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3086 pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, " pkgFlags=["); 3087 assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA"); 3088 privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3089 " privatePkgFlags=["); 3090 assertThat(privatePkgFlags).contains("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE"); 3091 assertThat(privatePkgFlags).contains("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA"); 3092 pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3093 " pendingRestore="); 3094 assertThat(pendingRestore).isEqualTo("true"); 3095 assertDataAppExists(HELLO_WORLD_PACKAGE_NAME); 3096 } 3097 3098 /** 3099 * Test that broadcasts are sent during archival install. 3100 */ 3101 @Test testInstallArchivedBroadcasts()3102 public void testInstallArchivedBroadcasts() throws Exception { 3103 int currentUser = ActivityManager.getCurrentUser(); 3104 final PackageBroadcastReceiver addedBroadcastReceiver = new PackageBroadcastReceiver( 3105 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_ADDED 3106 ); 3107 final PackageBroadcastReceiver removedBroadcastReceiver = new PackageBroadcastReceiver( 3108 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_REMOVED 3109 ); 3110 final PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver( 3111 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_UID_REMOVED 3112 ); 3113 final IntentFilter intentFilter = new IntentFilter(); 3114 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 3115 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 3116 intentFilter.addDataScheme("package"); 3117 final IntentFilter intentFilterForUidRemoved = new IntentFilter(Intent.ACTION_UID_REMOVED); 3118 mContext.registerReceiver(addedBroadcastReceiver, intentFilter); 3119 mContext.registerReceiver(removedBroadcastReceiver, intentFilter); 3120 mContext.registerReceiver(uidRemovedBroadcastReceiver, intentFilterForUidRemoved); 3121 3122 try { 3123 installPackage(HELLO_WORLD_APK); 3124 // Make sure this broadcast is received so it doesn't affect the test later 3125 addedBroadcastReceiver.assertBroadcastReceived(); 3126 byte[] archivedPackage = SystemUtil.runShellCommandByteOutput( 3127 mInstrumentation.getUiAutomation(), 3128 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME); 3129 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3130 // Make sure this broadcast is received so it doesn't affect the test later 3131 removedBroadcastReceiver.assertBroadcastReceived(); 3132 uidRemovedBroadcastReceiver.assertBroadcastReceived(); 3133 3134 addedBroadcastReceiver.reset(); 3135 removedBroadcastReceiver.reset(); 3136 uidRemovedBroadcastReceiver.reset(); 3137 3138 assertEquals("Success\n", executeShellCommand( 3139 String.format("pm install-archived -r -i %s -t -S %s", 3140 mContext.getPackageName(), archivedPackage.length), archivedPackage)); 3141 3142 addedBroadcastReceiver.assertBroadcastReceived(); 3143 Intent addedIntent = addedBroadcastReceiver.getBroadcastResult(); 3144 assertNotNull(addedIntent); 3145 assertTrue(addedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false)); 3146 assertFalse(addedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)); 3147 3148 removedBroadcastReceiver.assertBroadcastReceived(); 3149 Intent removedIntent = removedBroadcastReceiver.getBroadcastResult(); 3150 assertNotNull(removedIntent); 3151 assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false)); 3152 assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)); 3153 3154 uidRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3155 } finally { 3156 mContext.unregisterReceiver(addedBroadcastReceiver); 3157 mContext.unregisterReceiver(removedBroadcastReceiver); 3158 mContext.unregisterReceiver(uidRemovedBroadcastReceiver); 3159 } 3160 } 3161 3162 // Same tests as above, but using direct PackageInstaller API calls. 3163 3164 @Test 3165 @RequiresFlagsEnabled(FLAG_ARCHIVING) testInstallArchivedApiFromArchived()3166 public void testInstallArchivedApiFromArchived() throws Exception { 3167 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3168 3169 assertEquals("Success\n", SystemUtil.runShellCommand( 3170 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(), 3171 HELLO_WORLD_APK))); 3172 assertThat(SystemUtil.runShellCommand( 3173 String.format("pm archive %s", HELLO_WORLD_PACKAGE_NAME))).isEqualTo("Success\n"); 3174 3175 var packageManager = mContext.getPackageManager(); 3176 var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME); 3177 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3178 3179 // Install a default APK. 3180 installArchived(archivedPackage); 3181 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3182 // Check "installed" flag. 3183 var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 3184 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo; 3185 assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0); 3186 // Check archive state. 3187 assertTrue(applicationInfo.isArchived); 3188 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3189 } 3190 3191 @Test 3192 @RequiresFlagsEnabled(FLAG_ARCHIVING) testInstallArchivedApiUpdate()3193 public void testInstallArchivedApiUpdate() throws Exception { 3194 var packageManager = mContext.getPackageManager(); 3195 3196 installPackage(HELLO_WORLD_APK); 3197 var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME); 3198 3199 // Try to install archived on top of fully installed app. 3200 installArchived(archivedPackage, STATUS_FAILURE, 3201 "INSTALL_FAILED_SESSION_INVALID: Archived installation"); 3202 3203 // Uninstall and retry. 3204 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3205 installArchived(archivedPackage); 3206 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3207 assertDataAppExists(HELLO_WORLD_PACKAGE_NAME); 3208 // Wrong signature. 3209 assertThat(SystemUtil.runShellCommand( 3210 "pm install -t -g " + HELLO_WORLD_DIFF_SIGNER_APK)).startsWith( 3211 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE"); 3212 // Update fails because we can't derive an existing APK. 3213 assertThat(SystemUtil.runShellCommand( 3214 "pm install -t -p " + HELLO_WORLD_PACKAGE_NAME + " -g " 3215 + HELLO_WORLD_UPDATED_APK)).startsWith( 3216 "Failure [INSTALL_FAILED_INVALID_APK: Missing existing base package"); 3217 // Unarchive/full install succeeds. 3218 assertEquals("Success\n", SystemUtil.runShellCommand( 3219 "pm install -t -g " + HELLO_WORLD_UPDATED_APK)); 3220 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 3221 // Uninstall, keep data. 3222 assertEquals("Success\n", 3223 SystemUtil.runShellCommand("pm uninstall -k " + HELLO_WORLD_PACKAGE_NAME)); 3224 // Full uninstall. 3225 assertEquals("Success\n", 3226 SystemUtil.runShellCommand("pm uninstall " + HELLO_WORLD_PACKAGE_NAME)); 3227 assertFalse(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3228 } 3229 3230 @Test 3231 @RequiresFlagsEnabled(FLAG_ARCHIVING) testInstallArchivedApiCheckFlags()3232 public void testInstallArchivedApiCheckFlags() throws Exception { 3233 var packageManager = mContext.getPackageManager(); 3234 3235 installPackage(HELLO_WORLD_APK); 3236 var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME); 3237 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3238 3239 // Install a default APK. 3240 installArchived(archivedPackage); 3241 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3242 String pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, " pkgFlags=["); 3243 assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA"); 3244 assertThat(pkgFlags).contains("ALLOW_BACKUP"); 3245 String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3246 " privatePkgFlags=["); 3247 assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE"); 3248 assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA"); 3249 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3250 3251 installPackage(HELLO_WORLD_FLAGS_APK); 3252 var archivedPackageFlags = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME); 3253 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3254 3255 // Install an APK with non default flags. 3256 installArchived(archivedPackageFlags); 3257 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3258 pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, " pkgFlags=["); 3259 assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA"); 3260 privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, 3261 " privatePkgFlags=["); 3262 assertThat(privatePkgFlags).contains("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE"); 3263 assertThat(privatePkgFlags).contains("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA"); 3264 assertDataAppExists(HELLO_WORLD_PACKAGE_NAME); 3265 } 3266 3267 @Test 3268 @RequiresFlagsEnabled(FLAG_ARCHIVING) testInstallArchivedApiBroadcasts()3269 public void testInstallArchivedApiBroadcasts() throws Exception { 3270 var packageManager = mContext.getPackageManager(); 3271 3272 installPackage(HELLO_WORLD_APK); 3273 var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME); 3274 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3275 3276 // Wait ACTION_PACKAGE_REMOVED was dispatched for uninstall HELLO_WORLD_PACKAGE_NAME 3277 SystemClock.sleep(2_000); 3278 3279 int currentUser = ActivityManager.getCurrentUser(); 3280 final PackageBroadcastReceiver addedBroadcastReceiver = new PackageBroadcastReceiver( 3281 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_ADDED 3282 ); 3283 final PackageBroadcastReceiver removedBroadcastReceiver = new PackageBroadcastReceiver( 3284 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_REMOVED 3285 ); 3286 final PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver( 3287 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_UID_REMOVED 3288 ); 3289 final IntentFilter intentFilter = new IntentFilter(); 3290 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 3291 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 3292 intentFilter.addDataScheme("package"); 3293 final IntentFilter intentFilterForUidRemoved = new IntentFilter(Intent.ACTION_UID_REMOVED); 3294 mContext.registerReceiver(addedBroadcastReceiver, intentFilter); 3295 mContext.registerReceiver(removedBroadcastReceiver, intentFilter); 3296 mContext.registerReceiver(uidRemovedBroadcastReceiver, intentFilterForUidRemoved); 3297 3298 try { 3299 installArchived(archivedPackage); 3300 3301 addedBroadcastReceiver.assertBroadcastReceived(); 3302 Intent addedIntent = addedBroadcastReceiver.getBroadcastResult(); 3303 assertNotNull(addedIntent); 3304 assertTrue(addedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false)); 3305 assertFalse(addedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)); 3306 3307 removedBroadcastReceiver.assertBroadcastReceived(); 3308 Intent removedIntent = removedBroadcastReceiver.getBroadcastResult(); 3309 assertNotNull(removedIntent); 3310 assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false)); 3311 assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)); 3312 3313 uidRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3314 } finally { 3315 mContext.unregisterReceiver(addedBroadcastReceiver); 3316 mContext.unregisterReceiver(removedBroadcastReceiver); 3317 mContext.unregisterReceiver(uidRemovedBroadcastReceiver); 3318 } 3319 } 3320 readCertificate()3321 private static Certificate readCertificate() throws Exception { 3322 try (InputStream is = new FileInputStream(DIFF_SIGNER_CERTIFICATE)) { 3323 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 3324 return certFactory.generateCertificate(is); 3325 } 3326 } 3327 3328 @Test 3329 @RequiresFlagsEnabled(FLAG_ARCHIVING) testInstallArchivedApi()3330 public void testInstallArchivedApi() throws Exception { 3331 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3332 3333 Certificate certificate = readCertificate(); 3334 Signature signature = new Signature(new Certificate[] { certificate }); 3335 PublicKey publicKey = certificate.getPublicKey(); 3336 3337 SigningInfo signingInfo = new SigningInfo(/* schemeVersion= */3, List.of(signature), 3338 List.of(publicKey), null); 3339 3340 var wrongLabel = "HelloWorldTitle1"; 3341 var wrongComponent = new ComponentName(HELLO_WORLD_PACKAGE_NAME, ".MainActivity1"); 3342 3343 var archivedActivity = new ArchivedActivityInfo(wrongLabel, wrongComponent); 3344 assertEquals("HelloWorldTitle1", archivedActivity.getLabel()); 3345 assertEquals(wrongComponent, archivedActivity.getComponentName()); 3346 3347 var correctLabel = "HelloWorldTitle"; 3348 var correctComponent = new ComponentName(HELLO_WORLD_PACKAGE_NAME, ".MainActivity"); 3349 var icon = new BitmapDrawable(/* res= */null, TEST_ICON); 3350 var monochromeIcon = new BitmapDrawable(/* res= */null, TEST_ICON_MONO); 3351 3352 archivedActivity.setLabel(correctLabel); 3353 assertEquals(correctLabel, archivedActivity.getLabel()); 3354 archivedActivity.setComponentName(correctComponent); 3355 assertEquals(correctComponent, archivedActivity.getComponentName()); 3356 archivedActivity.setIcon(icon); 3357 assertEquals(icon, archivedActivity.getIcon()); 3358 archivedActivity.setMonochromeIcon(monochromeIcon); 3359 assertEquals(monochromeIcon, archivedActivity.getMonochromeIcon()); 3360 3361 var activities = List.of(archivedActivity); 3362 3363 var wrongPackageName = PACKAGE_NAME; 3364 var wrongSigningInfo = new SigningInfo(); 3365 var wrongLauncherActivities = new ArrayList<ArchivedActivityInfo>(); 3366 3367 var archivedPackage = new ArchivedPackageInfo(wrongPackageName, 3368 wrongSigningInfo, wrongLauncherActivities); 3369 assertEquals(wrongPackageName, archivedPackage.getPackageName()); 3370 assertEquals(wrongSigningInfo, archivedPackage.getSigningInfo()); 3371 assertEquals(wrongLauncherActivities, archivedPackage.getLauncherActivities()); 3372 3373 archivedPackage.setPackageName(HELLO_WORLD_PACKAGE_NAME); 3374 assertEquals(HELLO_WORLD_PACKAGE_NAME, archivedPackage.getPackageName()); 3375 archivedPackage.setSigningInfo(signingInfo); 3376 assertEquals(signingInfo, archivedPackage.getSigningInfo()); 3377 assertEquals(3, archivedPackage.getSigningInfo().getSchemeVersion()); 3378 assertThat(archivedPackage.getSigningInfo().getPublicKeys()).containsExactlyElementsIn( 3379 List.of(publicKey)); 3380 archivedPackage.setLauncherActivities(activities); 3381 assertEquals(activities, archivedPackage.getLauncherActivities()); 3382 archivedPackage.setVersionCode(1); 3383 assertEquals(1, archivedPackage.getVersionCode()); 3384 archivedPackage.setVersionCodeMajor(0); 3385 assertEquals(0, archivedPackage.getVersionCodeMajor()); 3386 archivedPackage.setTargetSdkVersion(27); 3387 assertEquals(27, archivedPackage.getTargetSdkVersion()); 3388 archivedPackage.setDefaultToDeviceProtectedStorage(null); 3389 assertNull(archivedPackage.getDefaultToDeviceProtectedStorage()); 3390 archivedPackage.setRequestLegacyExternalStorage("true"); 3391 assertEquals("true", archivedPackage.getRequestLegacyExternalStorage()); 3392 archivedPackage.setUserDataFragile("true"); 3393 assertEquals("true", archivedPackage.getUserDataFragile()); 3394 3395 // Install archived. 3396 installArchived(archivedPackage); 3397 assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME)); 3398 3399 // Wrong signature (we are using cts-testkey1). 3400 assertThat(SystemUtil.runShellCommand( 3401 "pm install -t -g " + HELLO_WORLD_UPDATED_APK)).startsWith( 3402 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE"); 3403 // Unarchive/full install succeeds. 3404 assertEquals("Success\n", SystemUtil.runShellCommand( 3405 "pm install -t -g " + HELLO_WORLD_DIFF_SIGNER_APK)); 3406 assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)); 3407 3408 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3409 } 3410 3411 @Test testPackageRemovedBroadcastsSingleUser()3412 public void testPackageRemovedBroadcastsSingleUser() throws Exception { 3413 installPackage(HELLO_WORLD_APK); 3414 final int currentUser = ActivityManager.getCurrentUser(); 3415 final PackageBroadcastReceiver 3416 removedBroadcastReceiver = new PackageBroadcastReceiver( 3417 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_REMOVED 3418 ); 3419 final PackageBroadcastReceiver fullyRemovedBroadcastReceiver = new PackageBroadcastReceiver( 3420 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_FULLY_REMOVED 3421 ); 3422 final PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver( 3423 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_UID_REMOVED 3424 ); 3425 final IntentFilter intentFilter = new IntentFilter(); 3426 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 3427 intentFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); 3428 intentFilter.addDataScheme("package"); 3429 3430 final IntentFilter intentFilterForUidRemoved = new IntentFilter(Intent.ACTION_UID_REMOVED); 3431 mContext.registerReceiver(removedBroadcastReceiver, intentFilter); 3432 mContext.registerReceiver(fullyRemovedBroadcastReceiver, intentFilter); 3433 mContext.registerReceiver(uidRemovedBroadcastReceiver, intentFilterForUidRemoved); 3434 3435 try { 3436 // Test uninstall -k without --user 3437 uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME); 3438 removedBroadcastReceiver.assertBroadcastReceived(); 3439 fullyRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3440 uidRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3441 removedBroadcastReceiver.reset(); 3442 // Test uninstall -k with --user 3443 installPackage(HELLO_WORLD_APK); 3444 uninstallPackageKeepDataForUser(HELLO_WORLD_PACKAGE_NAME, currentUser); 3445 removedBroadcastReceiver.assertBroadcastReceived(); 3446 fullyRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3447 uidRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3448 removedBroadcastReceiver.reset(); 3449 // Test uninstall without -k 3450 installPackage(HELLO_WORLD_APK); 3451 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3452 removedBroadcastReceiver.assertBroadcastReceived(); 3453 fullyRemovedBroadcastReceiver.assertBroadcastReceived(); 3454 uidRemovedBroadcastReceiver.assertBroadcastReceived(); 3455 removedBroadcastReceiver.reset(); 3456 fullyRemovedBroadcastReceiver.reset(); 3457 uidRemovedBroadcastReceiver.reset(); 3458 // Test uninstall --user without -k 3459 installPackage(HELLO_WORLD_APK); 3460 uninstallPackageForUser(HELLO_WORLD_PACKAGE_NAME, currentUser); 3461 removedBroadcastReceiver.assertBroadcastReceived(); 3462 fullyRemovedBroadcastReceiver.assertBroadcastReceived(); 3463 uidRemovedBroadcastReceiver.assertBroadcastReceived(); 3464 } finally { 3465 // Clean up 3466 mContext.unregisterReceiver(removedBroadcastReceiver); 3467 mContext.unregisterReceiver(fullyRemovedBroadcastReceiver); 3468 mContext.unregisterReceiver(uidRemovedBroadcastReceiver); 3469 } 3470 } 3471 3472 @Test testReinstallBroadcastsAfterDeleteKeepData()3473 public void testReinstallBroadcastsAfterDeleteKeepData() throws Exception { 3474 installPackage(HELLO_WORLD_APK); 3475 // Test uninstall -k 3476 uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME); 3477 final int currentUser = ActivityManager.getCurrentUser(); 3478 final PackageBroadcastReceiver 3479 replacedBroadcastReceiver = new PackageBroadcastReceiver( 3480 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_REPLACED 3481 ); 3482 final PackageBroadcastReceiver addedBroadcastReceiver = new PackageBroadcastReceiver( 3483 HELLO_WORLD_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_ADDED 3484 ); 3485 final IntentFilter intentFilter = new IntentFilter(); 3486 intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 3487 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 3488 intentFilter.addDataScheme("package"); 3489 mContext.registerReceiver(replacedBroadcastReceiver, intentFilter); 3490 mContext.registerReceiver(addedBroadcastReceiver, intentFilter); 3491 3492 try { 3493 // Reinstall and verify that the correct broadcasts are received 3494 installPackage(HELLO_WORLD_APK); 3495 replacedBroadcastReceiver.assertBroadcastReceived(); 3496 final Intent replacedIntent = replacedBroadcastReceiver.getBroadcastResult(); 3497 assertThat(replacedIntent).isNotNull(); 3498 assertThat( 3499 replacedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)).isTrue(); 3500 addedBroadcastReceiver.assertBroadcastReceived(); 3501 final Intent addedIntent = addedBroadcastReceiver.getBroadcastResult(); 3502 assertThat(addedIntent).isNotNull(); 3503 assertThat(addedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)).isTrue(); 3504 // Clean up 3505 uninstallPackage(HELLO_WORLD_PACKAGE_NAME); 3506 } finally { 3507 mContext.unregisterReceiver(replacedBroadcastReceiver); 3508 mContext.unregisterReceiver(addedBroadcastReceiver); 3509 } 3510 } 3511 3512 @Test testDeleteSystemApp()3513 public void testDeleteSystemApp() { 3514 PackageInfo ctsShimPackageInfo = null; 3515 try { 3516 ctsShimPackageInfo = mPackageManager.getPackageInfo( 3517 CTS_SHIM_PACKAGE_NAME, MATCH_SYSTEM_ONLY); 3518 } catch (NameNotFoundException e) { 3519 Log.w(TAG, "Device doesn't have " + CTS_SHIM_PACKAGE_NAME + " installed, skipping"); 3520 } 3521 assumeTrue(ctsShimPackageInfo != null); 3522 final int currentUser = ActivityManager.getCurrentUser(); 3523 try { 3524 // Delete the system package with DELETE_SYSTEM_APP 3525 uninstallPackageForUser(CTS_SHIM_PACKAGE_NAME, currentUser); 3526 assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, currentUser, 3527 0)).isFalse(); 3528 assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, currentUser, 3529 MATCH_DISABLED_COMPONENTS)).isFalse(); 3530 assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, currentUser, 3531 MATCH_DISABLED_UNTIL_USED_COMPONENTS)).isFalse(); 3532 assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, currentUser, 3533 MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS)).isTrue(); 3534 } finally { 3535 installExistingPackageForUser(CTS_SHIM_PACKAGE_NAME, currentUser); 3536 } 3537 } 3538 3539 @Test testInstallSystemAppAsInstant()3540 public void testInstallSystemAppAsInstant() { 3541 PackageInfo ctsShimPackageInfo = null; 3542 try { 3543 ctsShimPackageInfo = mPackageManager.getPackageInfo( 3544 CTS_SHIM_PACKAGE_NAME, MATCH_SYSTEM_ONLY); 3545 } catch (NameNotFoundException e) { 3546 Log.w(TAG, "Device doesn't have " + CTS_SHIM_PACKAGE_NAME + " installed, skipping"); 3547 } 3548 assumeTrue(ctsShimPackageInfo != null); 3549 final int currentUser = ActivityManager.getCurrentUser(); 3550 try { 3551 // Delete the system package with DELETE_SYSTEM_APP 3552 uninstallPackageForUser(CTS_SHIM_PACKAGE_NAME, currentUser); 3553 String result = SystemUtil.runShellCommand( 3554 "pm install-existing --instant --user " + currentUser + " " 3555 + CTS_SHIM_PACKAGE_NAME); 3556 assertThat(result).contains("NameNotFoundException"); 3557 } finally { 3558 installExistingPackageForUser(CTS_SHIM_PACKAGE_NAME, currentUser); 3559 } 3560 } 3561 matchesInstalled(PackageManager pm, String packageName, int userId, long flag)3562 static boolean matchesInstalled(PackageManager pm, String packageName, int userId, long flag) { 3563 List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser( 3564 PackageManager.PackageInfoFlags.of(flag), userId); 3565 List<String> packageNames = packageInfos.stream() 3566 .map(p -> p.packageName) 3567 .toList(); 3568 return packageNames.contains(packageName); 3569 } 3570 3571 @Test 3572 @RequiresFlagsDisabled(FLAG_QUARANTINED_ENABLED) testQasDisabled()3573 public void testQasDisabled() throws Exception { 3574 testQas(false); 3575 } 3576 3577 @Test 3578 @RequiresFlagsEnabled(FLAG_QUARANTINED_ENABLED) testQasEnabled()3579 public void testQasEnabled() throws Exception { 3580 testQas(true); 3581 } 3582 testQas(boolean enabled)3583 private void testQas(boolean enabled) throws Exception { 3584 installPackage(HELLO_WORLD_APK); 3585 SystemUtil.runWithShellPermissionIdentity(() -> { 3586 String[] notset = mPackageManager.setPackagesSuspended( 3587 new String[]{HELLO_WORLD_PACKAGE_NAME}, true, null, null, null, 3588 FLAG_SUSPEND_QUARANTINED); 3589 assertEquals("", String.join(",", notset)); 3590 }); 3591 3592 // Flag treatment. 3593 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(HELLO_WORLD_PACKAGE_NAME, 0); 3594 assertTrue(appInfo.enabled); 3595 3596 // Default filtration of activities. 3597 List<ResolveInfo> activitiesResult; 3598 { 3599 // 1. queryIntentActivities 3600 final Intent intent = new Intent(ACTIVITY_ACTION_NAME); 3601 intent.setPackage(HELLO_WORLD_PACKAGE_NAME); 3602 activitiesResult = mPackageManager.queryIntentActivities(intent, 3603 PackageManager.ResolveInfoFlags.of(0)); 3604 assertEquals(activitiesResult.toString(), 1, activitiesResult.size()); 3605 assertEquals("com.example.helloworld.MainActivity", 3606 activitiesResult.get(0).activityInfo.name); 3607 3608 // 2. getActivityInfo 3609 var componentInfo = activitiesResult.get(0).getComponentInfo(); 3610 var activityInfo = mPackageManager.getActivityInfo( 3611 new ComponentName(componentInfo.packageName, componentInfo.name), 3612 PackageManager.ComponentInfoFlags.of(0)); 3613 assertNotNull(activityInfo); 3614 assertEquals(activityInfo.name, activitiesResult.get(0).activityInfo.name); 3615 3616 // 3. PackageManager.getPackageInfo(<PKG>, GET_ACTIVITIES) 3617 var packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME, 3618 PackageManager.PackageInfoFlags.of(GET_ACTIVITIES)); 3619 assertEquals(1, packageInfo.activities.length); 3620 assertEquals("com.example.helloworld.MainActivity", packageInfo.activities[0].name); 3621 3622 // 4. mPackageManager.getInstalledPackages(GET_ACTIVITIES); 3623 List<PackageInfo> pkgs = mPackageManager.getInstalledPackages( 3624 PackageManager.PackageInfoFlags.of(GET_ACTIVITIES)); 3625 PackageInfo pkgInfo = findPackageOrFail(pkgs, HELLO_WORLD_PACKAGE_NAME); 3626 assertEquals(1, pkgInfo.activities.length); 3627 assertEquals("com.example.helloworld.MainActivity", pkgInfo.activities[0].name); 3628 } 3629 3630 // Default filtration of services. 3631 List<ResolveInfo> servicesResult; 3632 { 3633 Intent intent = new Intent("com.example.helloworld.service"); 3634 intent.setPackage(HELLO_WORLD_PACKAGE_NAME); 3635 servicesResult = mPackageManager.queryIntentServices(intent, 0); 3636 if (servicesResult == null) { 3637 servicesResult = new ArrayList<>(); 3638 } 3639 } 3640 3641 // Match QAS services. 3642 List<ResolveInfo> servicesResult1; 3643 { 3644 Intent intent = new Intent("com.example.helloworld.service"); 3645 intent.setPackage(HELLO_WORLD_PACKAGE_NAME); 3646 servicesResult1 = mPackageManager.queryIntentServices(intent, 3647 PackageManager.ResolveInfoFlags.of(MATCH_QUARANTINED_COMPONENTS)); 3648 if (servicesResult1 == null) { 3649 servicesResult1 = new ArrayList<>(); 3650 } 3651 assertEquals(servicesResult1.toString(), 1, servicesResult1.size()); 3652 assertEquals("com.example.helloworld.TestService", 3653 servicesResult1.get(0).serviceInfo.name); 3654 } 3655 3656 // Default filtration of providers. 3657 final List<ResolveInfo> providersResult1; 3658 { 3659 Intent intent = new Intent("com.example.helloworld.provider"); 3660 intent.setPackage(HELLO_WORLD_PACKAGE_NAME); 3661 intent.setComponent(new ComponentName(HELLO_WORLD_PACKAGE_NAME, 3662 "com.example.helloworld.TestContentProvider")); 3663 providersResult1 = mPackageManager.queryIntentContentProviders(intent, 0); 3664 } 3665 3666 final List<ResolveInfo> providersResult2; 3667 { 3668 Intent intent = new Intent("com.example.helloworld.provider"); 3669 providersResult2 = mPackageManager.queryIntentContentProviders(intent, 0); 3670 } 3671 3672 final List<ResolveInfo> providersResult3; 3673 { 3674 Intent intent = new Intent("com.example.helloworld.provider"); 3675 intent.setPackage(HELLO_WORLD_PACKAGE_NAME); 3676 providersResult3 = mPackageManager.queryIntentContentProviders(intent, 0); 3677 } 3678 3679 ProviderInfo contentProvider = mPackageManager.resolveContentProvider( 3680 "com.example.helloworld.testcontentprovider", 0); 3681 3682 boolean providerFound = false; 3683 { 3684 final List<ProviderInfo> result = mPackageManager.queryContentProviders(null, 0, 0); 3685 for (int i = 0, size = result == null ? 0 : result.size(); i < size; 3686 ++i) { 3687 final ProviderInfo providerInfo = result.get(i); 3688 if ("com.example.helloworld.TestContentProvider".equals(providerInfo.name)) { 3689 providerFound = true; 3690 break; 3691 } 3692 } 3693 } 3694 3695 if (enabled) { 3696 assertTrue(isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3697 assertTrue(servicesResult.toString(), servicesResult.size() == 0); 3698 assertTrue(providersResult1.toString(), providersResult1.size() == 0); 3699 assertTrue(providersResult2.toString(), providersResult2.size() == 0); 3700 assertTrue(providersResult3.toString(), providersResult3.size() == 0); 3701 assertFalse(providerFound); 3702 } else { 3703 assertFalse(isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3704 assertEquals(servicesResult.toString(), 1, servicesResult.size()); 3705 assertEquals("com.example.helloworld.TestService", 3706 servicesResult.get(0).serviceInfo.name); 3707 assertEquals(providersResult1.toString(), 1, providersResult1.size()); 3708 assertEquals("com.example.helloworld.TestContentProvider", 3709 providersResult1.get(0).providerInfo.name); 3710 assertEquals(providersResult2.toString(), 1, providersResult2.size()); 3711 assertEquals("com.example.helloworld.TestContentProvider", 3712 providersResult2.get(0).providerInfo.name); 3713 assertEquals(providersResult3.toString(), 1, providersResult3.size()); 3714 assertEquals("com.example.helloworld.TestContentProvider", 3715 providersResult3.get(0).providerInfo.name); 3716 assertNotNull(contentProvider); 3717 assertEquals("com.example.helloworld.TestContentProvider", 3718 contentProvider.name); 3719 assertTrue(providerFound); 3720 } 3721 } 3722 3723 @Test 3724 @RequiresFlagsEnabled(FLAG_QUARANTINED_ENABLED) testQasPrecedence()3725 public void testQasPrecedence() throws Exception { 3726 var ctsPackageName = mContext.getPackageName(); 3727 var userId = mContext.getUserId(); 3728 3729 installPackage(HELLO_WORLD_APK); 3730 3731 // Suspend by shell. 3732 SystemUtil.runShellCommand("pm suspend --user " + userId + " " + HELLO_WORLD_PACKAGE_NAME); 3733 assertTrue("package is suspended by shell", isPackageSuspended(HELLO_WORLD_PACKAGE_NAME)); 3734 assertFalse("package is not quarantined", isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3735 3736 // QAS as cts. 3737 var builder = new SuspendDialogInfo.Builder(); 3738 builder.setTitle("qas-ed by cts"); 3739 builder.setMessage("test message"); 3740 builder.setNeutralButtonText("test neutral message"); 3741 var dialogInfo = builder.build(); 3742 3743 SystemUtil.runWithShellPermissionIdentity(() -> { 3744 String[] notset = mPackageManager.setPackagesSuspended( 3745 new String[]{HELLO_WORLD_PACKAGE_NAME}, true, 3746 null, null, dialogInfo, FLAG_SUSPEND_QUARANTINED); 3747 assertEquals("", String.join(",", notset)); 3748 }, QUARANTINE_APPS); 3749 assertTrue("package is quarantined by both shell and cts", 3750 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3751 assertEquals(ctsPackageName, 3752 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME)); 3753 3754 // Un-suspend as shell. 3755 SystemUtil.runShellCommand("pm unsuspend --user " + userId + " " 3756 + HELLO_WORLD_PACKAGE_NAME); 3757 assertTrue("package is still quarantined by cts", 3758 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3759 // Still "cts" package. 3760 assertEquals(ctsPackageName, 3761 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME)); 3762 3763 // No effect. 3764 SystemUtil.runShellCommand("pm unsuspend --user " + userId + " " 3765 + HELLO_WORLD_PACKAGE_NAME); 3766 assertTrue("package is still quarantined by cts", 3767 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3768 assertEquals(ctsPackageName, 3769 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME)); 3770 3771 // QAS as shell. 3772 SystemUtil.runShellCommand("pm suspend-quarantine --dialogMessage shell-message " 3773 + "--user " + userId + " " + HELLO_WORLD_PACKAGE_NAME); 3774 assertTrue("package is quarantined by shell and cts", 3775 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3776 3777 // Un-quarantine by cts. 3778 SystemUtil.runWithShellPermissionIdentity(() -> { 3779 String[] notset = 3780 mPackageManager.setPackagesSuspended(new String[]{HELLO_WORLD_PACKAGE_NAME}, 3781 false, null, null, null, FLAG_SUSPEND_QUARANTINED); 3782 assertEquals("", String.join(",", notset)); 3783 }, QUARANTINE_APPS); 3784 assertEquals("com.android.shell", 3785 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME)); 3786 3787 // Unsuspend by shell. 3788 SystemUtil.runShellCommand("pm unsuspend --user " + userId + " " 3789 + HELLO_WORLD_PACKAGE_NAME); 3790 assertFalse("not quarantined anymore", isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME)); 3791 } 3792 3793 @Test 3794 @RequiresFlagsEnabled(FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS) testUidRemovedBroadcastNotReceivedForSharedUid()3795 public void testUidRemovedBroadcastNotReceivedForSharedUid() throws Exception { 3796 // Installing a test app that shares SYSTEM_UID 3797 var result = SystemUtil.runShellCommand("pm install -t -g " + HELLO_WORLD_SETTINGS); 3798 if (result.contains("no signatures that match those in shared user android.uid.system")) { 3799 // This test only works if platform and cts are built using the same certificate. 3800 return; 3801 } 3802 if (!Build.IS_DEBUGGABLE) { 3803 // Non-debuggable builds don't allow non-preloaded apps that use system certificate. 3804 return; 3805 } 3806 assertThat(result).isEqualTo("Success\n"); 3807 assertTrue(isPackagePresent(HELLO_WORLD_SETTINGS_PACKAGE_NAME)); 3808 int currentUser = ActivityManager.getCurrentUser(); 3809 PackageBroadcastReceiver packageRemovedBroadcastReceiver = new PackageBroadcastReceiver( 3810 HELLO_WORLD_SETTINGS_PACKAGE_NAME, currentUser, Intent.ACTION_PACKAGE_REMOVED 3811 ); 3812 final IntentFilter packageRemovedIntentFilter = 3813 new IntentFilter(Intent.ACTION_PACKAGE_REMOVED); 3814 packageRemovedIntentFilter.addDataScheme("package"); 3815 PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver( 3816 HELLO_WORLD_SETTINGS_PACKAGE_NAME, currentUser, Intent.ACTION_UID_REMOVED 3817 ); 3818 final IntentFilter uidRemovedIntentFilter = new IntentFilter(Intent.ACTION_UID_REMOVED); 3819 mContext.registerReceiver(packageRemovedBroadcastReceiver, packageRemovedIntentFilter); 3820 mContext.registerReceiver(uidRemovedBroadcastReceiver, uidRemovedIntentFilter); 3821 3822 try { 3823 uninstallPackage(HELLO_WORLD_SETTINGS_PACKAGE_NAME); 3824 packageRemovedBroadcastReceiver.assertBroadcastReceived(); 3825 uidRemovedBroadcastReceiver.assertBroadcastNotReceived(); 3826 } finally { 3827 mContext.unregisterReceiver(packageRemovedBroadcastReceiver); 3828 mContext.unregisterReceiver(uidRemovedBroadcastReceiver); 3829 } 3830 } 3831 isPackageSuspended(String packageName)3832 private boolean isPackageSuspended(String packageName) { 3833 return SystemUtil.runWithShellPermissionIdentity( 3834 () -> mPackageManager.isPackageSuspended(packageName)); 3835 } 3836 isPackageQuarantined(String packageName)3837 private boolean isPackageQuarantined(String packageName) { 3838 return SystemUtil.runWithShellPermissionIdentity( 3839 () -> mPackageManager.isPackageQuarantined(packageName)); 3840 } 3841 sendIntent(IntentSender intentSender)3842 private void sendIntent(IntentSender intentSender) throws IntentSender.SendIntentException { 3843 intentSender.sendIntent(mContext, 0 /* code */, null /* intent */, 3844 null /* onFinished */, null /* handler */, null /* requiredPermission */, 3845 ActivityOptions.makeBasic().setPendingIntentBackgroundActivityStartMode( 3846 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED).toBundle()); 3847 } 3848 getInstalledState(String packageName, int userId)3849 static String getInstalledState(String packageName, int userId) { 3850 final String commandResult = SystemUtil.runShellCommand("pm dump " + packageName); 3851 final String userStatesLine = Arrays.stream(commandResult.split("\\r?\\n")) 3852 .filter(line -> line.startsWith(" User " + userId + ":")) 3853 .findFirst() 3854 .orElse(null); 3855 if (userStatesLine == null) { 3856 return null; 3857 } 3858 final String key = "installed="; 3859 final int keyStart = userStatesLine.indexOf(key); 3860 if (keyStart < 0) { 3861 return null; 3862 } 3863 final int keyEnd = userStatesLine.indexOf(key) + key.length(); 3864 final int valueEnd = userStatesLine.indexOf(" ", keyEnd); 3865 return userStatesLine.substring(keyEnd, valueEnd); 3866 } 3867 3868 @Test 3869 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO) testParseAndroidManifest_withNullApkFile()3870 public void testParseAndroidManifest_withNullApkFile() { 3871 // Disallow the apk file is null 3872 assertThrows(NullPointerException.class, 3873 () -> mPackageManager.parseAndroidManifest((File) null /* apkFile */, 3874 xmlResourceParser -> new Bundle())); 3875 } 3876 3877 @Test 3878 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO) testParseAndroidManifest_withNullParserFunction()3879 public void testParseAndroidManifest_withNullParserFunction() { 3880 // Disallow the parser function is null 3881 assertThrows(NullPointerException.class, 3882 () -> mPackageManager.parseAndroidManifest(new File(mContext.getPackageCodePath()), 3883 null /* parserFunction */)); 3884 } 3885 3886 @Test 3887 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO) testParseAndroidManifest_withInvalidApkFile()3888 public void testParseAndroidManifest_withInvalidApkFile() { 3889 assertThrows(IOException.class, 3890 () -> mPackageManager.parseAndroidManifest(new File("/data/app/invalid/base.apk"), 3891 xmlResourceParser -> new Bundle())); 3892 } 3893 3894 @Test 3895 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO) testParseAndroidManifest()3896 public void testParseAndroidManifest() { 3897 Bundle testResult; 3898 try { 3899 testResult = mPackageManager.parseAndroidManifest( 3900 new File(mContext.getPackageCodePath()), 3901 xmlResourceParser -> { 3902 assertNotNull(xmlResourceParser); 3903 3904 // Search the start tag 3905 int type = -1; 3906 try { 3907 while ((type = xmlResourceParser.next()) != XmlPullParser.START_TAG 3908 && type != XmlPullParser.END_DOCUMENT) { 3909 Log.d(TAG, "type=" + type); 3910 } 3911 } catch (Exception e) { 3912 Log.e(TAG, "Failure to parse next" + e); 3913 } 3914 3915 assertThat(type).isEqualTo(XmlPullParser.START_TAG); 3916 assertThat(xmlResourceParser.getName()).isEqualTo(TAG_MANIFEST); 3917 assertThat(xmlResourceParser.getAttributeValue(null, "package")).isEqualTo( 3918 PACKAGE_NAME); 3919 3920 Bundle bundle = new Bundle(); 3921 bundle.putString("package", PACKAGE_NAME); 3922 return bundle; 3923 }); 3924 } catch (IOException e) { 3925 Log.e(TAG, "Failure to parse android manifest" + e); 3926 testResult = null; 3927 } 3928 3929 assertNotNull(testResult); 3930 assertThat(testResult.getString("package")).isEqualTo(PACKAGE_NAME); 3931 } 3932 3933 @Test 3934 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD) testParseAndroidManifestWithFd_withNullApkFileDescriptor()3935 public void testParseAndroidManifestWithFd_withNullApkFileDescriptor() { 3936 // Disallow the apk fd is null 3937 assertThrows(NullPointerException.class, 3938 () -> mPackageManager.parseAndroidManifest((ParcelFileDescriptor) null, 3939 xmlResourceParser -> new Bundle())); 3940 } 3941 3942 @Test 3943 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD) testParseAndroidManifestWithFd_withNullParserFunction()3944 public void testParseAndroidManifestWithFd_withNullParserFunction() { 3945 // Disallow the parser function is null 3946 assertThrows(NullPointerException.class, 3947 () -> mPackageManager.parseAndroidManifest( 3948 ParcelFileDescriptor.open(new File( 3949 mContext.getPackageCodePath()), 3950 ParcelFileDescriptor.MODE_READ_ONLY), 3951 null /* parserFunction */)); 3952 } 3953 3954 @Test 3955 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD) testParseAndroidManifestWithFd_withInvalidApkFile()3956 public void testParseAndroidManifestWithFd_withInvalidApkFile() { 3957 assertThrows(IOException.class, 3958 () -> mPackageManager.parseAndroidManifest( 3959 ParcelFileDescriptor.open(new File("/data/app/invalid/base.apk"), 3960 ParcelFileDescriptor.MODE_READ_ONLY), 3961 xmlResourceParser -> new Bundle())); 3962 } 3963 3964 @Test 3965 @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD) testParseAndroidManifestWithFd()3966 public void testParseAndroidManifestWithFd() { 3967 Bundle testResult; 3968 try { 3969 testResult = mPackageManager.parseAndroidManifest( 3970 ParcelFileDescriptor.open(new File(mContext.getPackageCodePath()), 3971 ParcelFileDescriptor.MODE_READ_ONLY), 3972 xmlResourceParser -> { 3973 assertNotNull(xmlResourceParser); 3974 3975 // Search the start tag 3976 int type = -1; 3977 try { 3978 while ((type = xmlResourceParser.next()) != XmlPullParser.START_TAG 3979 && type != XmlPullParser.END_DOCUMENT) { 3980 Log.d(TAG, "type=" + type); 3981 } 3982 } catch (Exception e) { 3983 Log.e(TAG, "Failure to parse next" + e); 3984 } 3985 3986 assertThat(type).isEqualTo(XmlPullParser.START_TAG); 3987 assertThat(xmlResourceParser.getName()).isEqualTo(TAG_MANIFEST); 3988 assertThat(xmlResourceParser.getAttributeValue(null, "package")).isEqualTo( 3989 PACKAGE_NAME); 3990 3991 Bundle bundle = new Bundle(); 3992 bundle.putString("package", PACKAGE_NAME); 3993 return bundle; 3994 }); 3995 } catch (IOException e) { 3996 Log.e(TAG, "Failure to parse android manifest" + e); 3997 testResult = null; 3998 } 3999 4000 assertNotNull(testResult); 4001 assertThat(testResult.getString("package")).isEqualTo(PACKAGE_NAME); 4002 } 4003 4004 @Test 4005 @RequiresFlagsEnabled(FLAG_MIN_TARGET_SDK_24) 4006 @CddTest(requirements = {"3.1/C-0-8"}) testInstallTargetSdk23Fail()4007 public void testInstallTargetSdk23Fail() { 4008 assertThat(installPackageWithResult(CTS_TARGET_SDK_23)).contains( 4009 "INSTALL_FAILED_DEPRECATED_SDK_VERSION"); 4010 assertThat(installPackage(CTS_TARGET_SDK_24)).isTrue(); 4011 } 4012 4013 @Test 4014 @RequiresFlagsEnabled(FLAG_MIN_TARGET_SDK_24) 4015 @CddTest(requirements = {"3.1/C-0-8"}) testInstallTargetSdk23Bypass()4016 public void testInstallTargetSdk23Bypass() { 4017 String result = SystemUtil.runShellCommand( 4018 "pm install -t -g --bypass-low-target-sdk-block " + CTS_TARGET_SDK_23); 4019 assertThat(result).isEqualTo("Success\n"); 4020 assertThat(installPackage(CTS_TARGET_SDK_24)).isTrue(); 4021 } 4022 4023 @Test 4024 @RequiresFlagsDisabled(FLAG_MIN_TARGET_SDK_24) 4025 @CddTest(requirements = {"3.1/C-0-8"}) testInstallTargetSdk23Success()4026 public void testInstallTargetSdk23Success() { 4027 assertThat(installPackage(CTS_TARGET_SDK_23)).isTrue(); 4028 assertThat(installPackage(CTS_TARGET_SDK_24)).isTrue(); 4029 } 4030 setUpdateMimeGroupAndAssertBroadcasts(Set<String> mimeTypes, boolean isBroadcastReceived)4031 private void setUpdateMimeGroupAndAssertBroadcasts(Set<String> mimeTypes, 4032 boolean isBroadcastReceived) throws Exception { 4033 final String expectedPackageName = mContext.getPackageName(); 4034 final IntentFilter filter = new IntentFilter(); 4035 filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 4036 filter.addDataScheme("package"); 4037 final PackageBroadcastReceiver packageChangedBroadcastReceiver = 4038 new PackageBroadcastReceiver(expectedPackageName, 4039 ActivityManager.getCurrentUser(), Intent.ACTION_PACKAGE_CHANGED); 4040 mContext.registerReceiver(packageChangedBroadcastReceiver, filter, RECEIVER_EXPORTED); 4041 try { 4042 mPackageManager.setMimeGroup(MIME_GROUP, mimeTypes); 4043 if (isBroadcastReceived) { 4044 packageChangedBroadcastReceiver.assertBroadcastReceived(); 4045 final Intent resultIntent = packageChangedBroadcastReceiver.getBroadcastResult(); 4046 final String[] receivedComponents = resultIntent.getStringArrayExtra( 4047 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); 4048 assertThat(receivedComponents).isNotNull(); 4049 assertThat(receivedComponents[0]).isEqualTo(expectedPackageName); 4050 assertThat(mPackageManager.getMimeGroup(MIME_GROUP)).isEqualTo(mimeTypes); 4051 } else { 4052 packageChangedBroadcastReceiver.assertBroadcastNotReceived(); 4053 } 4054 } finally { 4055 mContext.unregisterReceiver(packageChangedBroadcastReceiver); 4056 } 4057 } 4058 4059 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, 4060 codeName = "VanillaIceCream") 4061 @Test testUpdateMimeGroup_changed()4062 public void testUpdateMimeGroup_changed() throws Exception { 4063 Set<String> mimeTypes = Collections.singleton("text/*"); 4064 4065 setUpdateMimeGroupAndAssertBroadcasts(mimeTypes, /* isBroadcastReceived= */ true); 4066 assertThat(mPackageManager.getMimeGroup(MIME_GROUP)).isEqualTo(mimeTypes); 4067 } 4068 4069 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, 4070 codeName = "VanillaIceCream") 4071 @Test testUpdateMimeGroup_noChanged_noBroadcastReceived()4072 public void testUpdateMimeGroup_noChanged_noBroadcastReceived() throws Exception { 4073 final Set<String> mimeTypes = Collections.singleton("image/*"); 4074 4075 setUpdateMimeGroupAndAssertBroadcasts(mimeTypes, /* isBroadcastReceived= */ true); 4076 assertThat(mPackageManager.getMimeGroup(MIME_GROUP)).isEqualTo(mimeTypes); 4077 setUpdateMimeGroupAndAssertBroadcasts(mimeTypes, /* isBroadcastReceived= */ false); 4078 } 4079 } 4080