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