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