1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.appenumeration.cts; 18 19 import static android.Manifest.permission.SET_PREFERRED_APPLICATIONS; 20 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 21 import static android.appenumeration.cts.Constants.ACTION_AWAIT_LAUNCHER_APPS_CALLBACK; 22 import static android.appenumeration.cts.Constants.ACTION_AWAIT_LAUNCHER_APPS_SESSION_CALLBACK; 23 import static android.appenumeration.cts.Constants.ACTION_BIND_SERVICE; 24 import static android.appenumeration.cts.Constants.ACTION_CAN_PACKAGE_QUERY; 25 import static android.appenumeration.cts.Constants.ACTION_CHECK_PACKAGE; 26 import static android.appenumeration.cts.Constants.ACTION_CHECK_SIGNATURES; 27 import static android.appenumeration.cts.Constants.ACTION_CHECK_URI_PERMISSION; 28 import static android.appenumeration.cts.Constants.ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS; 29 import static android.appenumeration.cts.Constants.ACTION_GET_ALL_SESSIONS; 30 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES; 31 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS; 32 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_PACKAGES; 33 import static android.appenumeration.cts.Constants.ACTION_GET_NAMES_FOR_UIDS; 34 import static android.appenumeration.cts.Constants.ACTION_GET_NAME_FOR_UID; 35 import static android.appenumeration.cts.Constants.ACTION_GET_PACKAGES_FOR_UID; 36 import static android.appenumeration.cts.Constants.ACTION_GET_PACKAGE_INFO; 37 import static android.appenumeration.cts.Constants.ACTION_GET_PREFERRED_ACTIVITIES; 38 import static android.appenumeration.cts.Constants.ACTION_GET_SESSION_INFO; 39 import static android.appenumeration.cts.Constants.ACTION_GET_SHAREDLIBRARY_DEPENDENT_PACKAGES; 40 import static android.appenumeration.cts.Constants.ACTION_GET_STAGED_SESSIONS; 41 import static android.appenumeration.cts.Constants.ACTION_GET_SYNCADAPTER_PACKAGES_FOR_AUTHORITY; 42 import static android.appenumeration.cts.Constants.ACTION_GET_SYNCADAPTER_TYPES; 43 import static android.appenumeration.cts.Constants.ACTION_GRANT_URI_PERMISSION; 44 import static android.appenumeration.cts.Constants.ACTION_HAS_SIGNING_CERTIFICATE; 45 import static android.appenumeration.cts.Constants.ACTION_JUST_FINISH; 46 import static android.appenumeration.cts.Constants.ACTION_LAUNCHER_APPS_GET_SUSPENDED_PACKAGE_LAUNCHER_EXTRAS; 47 import static android.appenumeration.cts.Constants.ACTION_LAUNCHER_APPS_IS_ACTIVITY_ENABLED; 48 import static android.appenumeration.cts.Constants.ACTION_LAUNCHER_APPS_SHOULD_HIDE_FROM_SUGGESTIONS; 49 import static android.appenumeration.cts.Constants.ACTION_MANIFEST_ACTIVITY; 50 import static android.appenumeration.cts.Constants.ACTION_MANIFEST_PROVIDER; 51 import static android.appenumeration.cts.Constants.ACTION_MANIFEST_SERVICE; 52 import static android.appenumeration.cts.Constants.ACTION_PENDING_INTENT_GET_ACTIVITY; 53 import static android.appenumeration.cts.Constants.ACTION_PENDING_INTENT_GET_CREATOR_PACKAGE; 54 import static android.appenumeration.cts.Constants.ACTION_QUERY_ACTIVITIES; 55 import static android.appenumeration.cts.Constants.ACTION_QUERY_PROVIDERS; 56 import static android.appenumeration.cts.Constants.ACTION_QUERY_RESOLVER; 57 import static android.appenumeration.cts.Constants.ACTION_QUERY_SERVICES; 58 import static android.appenumeration.cts.Constants.ACTION_REQUEST_SYNC_AND_AWAIT_STATUS; 59 import static android.appenumeration.cts.Constants.ACTION_REVOKE_URI_PERMISSION; 60 import static android.appenumeration.cts.Constants.ACTION_SET_INSTALLER_PACKAGE_NAME; 61 import static android.appenumeration.cts.Constants.ACTION_START_DIRECTLY; 62 import static android.appenumeration.cts.Constants.ACTION_START_FOR_RESULT; 63 import static android.appenumeration.cts.Constants.ACTION_TAKE_PERSISTABLE_URI_PERMISSION; 64 import static android.appenumeration.cts.Constants.ACTIVITY_CLASS_DUMMY_ACTIVITY; 65 import static android.appenumeration.cts.Constants.ACTIVITY_CLASS_TEST; 66 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_INVALID; 67 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_SUSPENDED; 68 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_UNSUSPENDED; 69 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_ADDED; 70 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_CHANGED; 71 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_REMOVED; 72 import static android.appenumeration.cts.Constants.EXTRA_ACCOUNT; 73 import static android.appenumeration.cts.Constants.EXTRA_AUTHORITY; 74 import static android.appenumeration.cts.Constants.EXTRA_CERT; 75 import static android.appenumeration.cts.Constants.EXTRA_DATA; 76 import static android.appenumeration.cts.Constants.EXTRA_ERROR; 77 import static android.appenumeration.cts.Constants.EXTRA_FLAGS; 78 import static android.appenumeration.cts.Constants.EXTRA_ID; 79 import static android.appenumeration.cts.Constants.EXTRA_PENDING_INTENT; 80 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK; 81 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_READY_CALLBACK; 82 import static android.appenumeration.cts.Constants.QUERIES_ACTIVITY_ACTION; 83 import static android.appenumeration.cts.Constants.QUERIES_NOTHING; 84 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PERM; 85 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PROVIDER; 86 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_Q; 87 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI; 88 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI_APK; 89 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_PERM_URI; 90 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI; 91 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI_APK; 92 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_URI; 93 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SEES_INSTALLER; 94 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SEES_INSTALLER_APK; 95 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SHARED_USER; 96 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_USES_LIBRARY; 97 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_USES_OPTIONAL_LIBRARY; 98 import static android.appenumeration.cts.Constants.QUERIES_PACKAGE; 99 import static android.appenumeration.cts.Constants.QUERIES_PACKAGE_PROVIDER; 100 import static android.appenumeration.cts.Constants.QUERIES_PROVIDER_ACTION; 101 import static android.appenumeration.cts.Constants.QUERIES_PROVIDER_AUTH; 102 import static android.appenumeration.cts.Constants.QUERIES_SERVICE_ACTION; 103 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_ACTIVITY_ACTION; 104 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_PROVIDER_ACTION; 105 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_PROVIDER_AUTH; 106 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_SERVICE_ACTION; 107 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_ACTION; 108 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_BROWSABLE; 109 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_BROWSER; 110 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_CONTACTS; 111 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_EDITOR; 112 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_SHARE; 113 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_WEB; 114 import static android.appenumeration.cts.Constants.TARGET_APPWIDGETPROVIDER; 115 import static android.appenumeration.cts.Constants.TARGET_APPWIDGETPROVIDER_SHARED_USER; 116 import static android.appenumeration.cts.Constants.TARGET_BROWSER; 117 import static android.appenumeration.cts.Constants.TARGET_BROWSER_WILDCARD; 118 import static android.appenumeration.cts.Constants.TARGET_CONTACTS; 119 import static android.appenumeration.cts.Constants.TARGET_EDITOR; 120 import static android.appenumeration.cts.Constants.TARGET_FILTERS; 121 import static android.appenumeration.cts.Constants.TARGET_FILTERS_APK; 122 import static android.appenumeration.cts.Constants.TARGET_FORCEQUERYABLE; 123 import static android.appenumeration.cts.Constants.TARGET_FORCEQUERYABLE_NORMAL; 124 import static android.appenumeration.cts.Constants.TARGET_NO_API; 125 import static android.appenumeration.cts.Constants.TARGET_PREFERRED_ACTIVITY; 126 import static android.appenumeration.cts.Constants.TARGET_PREFIX_WILDCARD_WEB; 127 import static android.appenumeration.cts.Constants.TARGET_SHARE; 128 import static android.appenumeration.cts.Constants.TARGET_SHARED_LIBRARY_PACKAGE; 129 import static android.appenumeration.cts.Constants.TARGET_SHARED_USER; 130 import static android.appenumeration.cts.Constants.TARGET_STUB; 131 import static android.appenumeration.cts.Constants.TARGET_STUB_APK; 132 import static android.appenumeration.cts.Constants.TARGET_SYNCADAPTER; 133 import static android.appenumeration.cts.Constants.TARGET_SYNCADAPTER_SHARED_USER; 134 import static android.appenumeration.cts.Constants.TARGET_WEB; 135 import static android.content.Intent.EXTRA_PACKAGES; 136 import static android.content.Intent.EXTRA_UID; 137 import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES; 138 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 139 import static android.content.pm.PackageManager.SIGNATURE_MATCH; 140 import static android.content.pm.PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 141 import static android.os.Process.INVALID_UID; 142 import static android.os.Process.ROOT_UID; 143 144 import static com.android.compatibility.common.util.ShellUtils.runShellCommand; 145 146 import static org.hamcrest.MatcherAssert.assertThat; 147 import static org.hamcrest.Matchers.arrayContainingInAnyOrder; 148 import static org.hamcrest.Matchers.containsString; 149 import static org.hamcrest.Matchers.emptyArray; 150 import static org.hamcrest.Matchers.emptyOrNullString; 151 import static org.hamcrest.Matchers.equalTo; 152 import static org.hamcrest.Matchers.greaterThan; 153 import static org.hamcrest.Matchers.greaterThanOrEqualTo; 154 import static org.hamcrest.Matchers.hasItemInArray; 155 import static org.hamcrest.Matchers.not; 156 import static org.hamcrest.Matchers.notNullValue; 157 import static org.hamcrest.core.Is.is; 158 import static org.junit.Assert.assertFalse; 159 import static org.junit.Assert.assertThrows; 160 import static org.junit.Assert.assertTrue; 161 import static org.junit.Assert.fail; 162 import static org.junit.Assume.assumeTrue; 163 164 import android.Manifest; 165 import android.accounts.Account; 166 import android.accounts.AccountManager; 167 import android.app.ActivityOptions; 168 import android.app.PendingIntent; 169 import android.appwidget.AppWidgetProviderInfo; 170 import android.content.ComponentName; 171 import android.content.Context; 172 import android.content.Intent; 173 import android.content.IntentFilter; 174 import android.content.SyncAdapterType; 175 import android.content.pm.LauncherApps; 176 import android.content.pm.PackageInfo; 177 import android.content.pm.PackageInstaller; 178 import android.content.pm.PackageInstaller.SessionInfo; 179 import android.content.pm.PackageManager; 180 import android.content.pm.Signature; 181 import android.content.res.Resources; 182 import android.net.Uri; 183 import android.os.Bundle; 184 import android.os.ConditionVariable; 185 import android.os.Handler; 186 import android.os.HandlerThread; 187 import android.os.Parcelable; 188 import android.os.Process; 189 import android.os.RemoteCallback; 190 191 import androidx.annotation.Nullable; 192 import androidx.test.ext.junit.runners.AndroidJUnit4; 193 import androidx.test.platform.app.InstrumentationRegistry; 194 195 import com.android.compatibility.common.util.AmUtils; 196 import com.android.compatibility.common.util.SystemUtil; 197 import com.android.cts.install.lib.Install; 198 import com.android.cts.install.lib.InstallUtils; 199 import com.android.cts.install.lib.LocalIntentSender; 200 import com.android.cts.install.lib.TestApp; 201 202 import org.hamcrest.core.IsNull; 203 import org.junit.AfterClass; 204 import org.junit.Assert; 205 import org.junit.BeforeClass; 206 import org.junit.Rule; 207 import org.junit.Test; 208 import org.junit.rules.TestName; 209 import org.junit.runner.RunWith; 210 211 import java.io.ByteArrayInputStream; 212 import java.io.InputStream; 213 import java.io.PrintWriter; 214 import java.io.StringWriter; 215 import java.security.cert.Certificate; 216 import java.security.cert.CertificateFactory; 217 import java.security.cert.X509Certificate; 218 import java.util.ArrayList; 219 import java.util.Arrays; 220 import java.util.List; 221 import java.util.Objects; 222 import java.util.UUID; 223 import java.util.concurrent.CountDownLatch; 224 import java.util.concurrent.TimeUnit; 225 import java.util.concurrent.TimeoutException; 226 import java.util.concurrent.atomic.AtomicReference; 227 228 @RunWith(AndroidJUnit4.class) 229 public class AppEnumerationTests { 230 private static Handler sResponseHandler; 231 private static HandlerThread sResponseThread; 232 233 private static boolean sGlobalFeatureEnabled; 234 235 private static PackageManager sPm; 236 private static AccountManager sAccountManager; 237 238 // The shared library for getting dependent packages 239 private static final String TEST_SHARED_LIB_NAME = "android.test.runner"; 240 private static final String TEST_NONEXISTENT_PACKAGE_NAME_1 = "com.android.cts.nonexistent1"; 241 private static final String TEST_NONEXISTENT_PACKAGE_NAME_2 = "com.android.cts.nonexistent2"; 242 243 private static final Account ACCOUNT_SYNCADAPTER = new Account( 244 TARGET_SYNCADAPTER, "android.appenumeration.account.type"); 245 private static final Account ACCOUNT_SYNCADAPTER_SHARED_USER = new Account( 246 TARGET_SYNCADAPTER_SHARED_USER, "android.appenumeration.shareduid.account.type"); 247 248 @Rule 249 public TestName name = new TestName(); 250 251 @BeforeClass setup()252 public static void setup() { 253 final String deviceConfigResponse = 254 SystemUtil.runShellCommand( 255 "device_config get package_manager_service " 256 + "package_query_filtering_enabled") 257 .trim(); 258 if ("null".equalsIgnoreCase(deviceConfigResponse) || deviceConfigResponse.isEmpty()) { 259 sGlobalFeatureEnabled = true; 260 } else { 261 sGlobalFeatureEnabled = Boolean.parseBoolean(deviceConfigResponse); 262 } 263 System.out.println("Feature enabled: " + sGlobalFeatureEnabled); 264 if (!sGlobalFeatureEnabled) return; 265 266 sResponseThread = new HandlerThread("response"); 267 sResponseThread.start(); 268 sResponseHandler = new Handler(sResponseThread.getLooper()); 269 270 sPm = InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); 271 sAccountManager = AccountManager.get( 272 InstrumentationRegistry.getInstrumentation().getContext()); 273 274 assertThat(sAccountManager.addAccountExplicitly(ACCOUNT_SYNCADAPTER, 275 null /* password */, null /* userdata */), is(true)); 276 assertThat(sAccountManager.addAccountExplicitly(ACCOUNT_SYNCADAPTER_SHARED_USER, 277 null /* password */, null /* userdata */), is(true)); 278 } 279 280 @AfterClass tearDown()281 public static void tearDown() { 282 if (!sGlobalFeatureEnabled) return; 283 sResponseThread.quit(); 284 285 assertThat(sAccountManager.removeAccountExplicitly(ACCOUNT_SYNCADAPTER), 286 is(true)); 287 assertThat(sAccountManager.removeAccountExplicitly(ACCOUNT_SYNCADAPTER_SHARED_USER), 288 is(true)); 289 } 290 291 @Test systemPackagesQueryable_notEnabled()292 public void systemPackagesQueryable_notEnabled() throws Exception { 293 final Resources resources = Resources.getSystem(); 294 assertFalse( 295 "config_forceSystemPackagesQueryable must not be true.", 296 resources.getBoolean(resources.getIdentifier( 297 "config_forceSystemPackagesQueryable", "bool", "android"))); 298 299 // now let's assert that that the actual set of system apps is limited 300 assertThat("Not all system apps should be visible.", 301 getInstalledPackages(QUERIES_NOTHING_PERM, MATCH_SYSTEM_ONLY).length, 302 greaterThan(getInstalledPackages(QUERIES_NOTHING, MATCH_SYSTEM_ONLY).length)); 303 } 304 305 @Test all_canSeeForceQueryable()306 public void all_canSeeForceQueryable() throws Exception { 307 assertVisible(QUERIES_NOTHING, TARGET_FORCEQUERYABLE); 308 assertVisible(QUERIES_ACTIVITY_ACTION, TARGET_FORCEQUERYABLE); 309 assertVisible(QUERIES_SERVICE_ACTION, TARGET_FORCEQUERYABLE); 310 assertVisible(QUERIES_PROVIDER_AUTH, TARGET_FORCEQUERYABLE); 311 assertVisible(QUERIES_PACKAGE, TARGET_FORCEQUERYABLE); 312 } 313 314 @Test all_cannotSeeForceQueryableInstalledNormally()315 public void all_cannotSeeForceQueryableInstalledNormally() throws Exception { 316 assertNotVisible(QUERIES_NOTHING, TARGET_FORCEQUERYABLE_NORMAL); 317 assertNotVisible(QUERIES_ACTIVITY_ACTION, TARGET_FORCEQUERYABLE_NORMAL); 318 assertNotVisible(QUERIES_SERVICE_ACTION, TARGET_FORCEQUERYABLE_NORMAL); 319 assertNotVisible(QUERIES_PROVIDER_AUTH, TARGET_FORCEQUERYABLE_NORMAL); 320 assertNotVisible(QUERIES_PACKAGE, TARGET_FORCEQUERYABLE_NORMAL); 321 } 322 323 @Test startExplicitly_canStartNonVisible()324 public void startExplicitly_canStartNonVisible() throws Exception { 325 assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS); 326 startExplicitIntentViaComponent(QUERIES_NOTHING, TARGET_FILTERS); 327 startExplicitIntentViaPackageName(QUERIES_NOTHING, TARGET_FILTERS); 328 } 329 330 @Test startExplicitly_canStartVisible()331 public void startExplicitly_canStartVisible() throws Exception { 332 assertVisible(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS); 333 startExplicitIntentViaComponent(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS); 334 startExplicitIntentViaPackageName(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS); 335 } 336 337 @Test startImplicitly_canStartNonVisible()338 public void startImplicitly_canStartNonVisible() throws Exception { 339 assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS); 340 startImplicitIntent(QUERIES_NOTHING); 341 } 342 343 @Test startActivityWithNoPermissionUri_canSeeProvider()344 public void startActivityWithNoPermissionUri_canSeeProvider() throws Exception { 345 assertNotVisible(QUERIES_NOTHING_RECEIVES_URI, QUERIES_NOTHING_PERM); 346 347 // send with uri but no grant flags; shouldn't be visible 348 startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_URI, 349 new Intent(ACTION_JUST_FINISH) 350 .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "/test"))); 351 assertNotVisible(QUERIES_NOTHING_RECEIVES_URI, QUERIES_NOTHING_PERM); 352 353 // send again with uri bug grant flags now set; should be visible 354 startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_URI, 355 new Intent(ACTION_JUST_FINISH) 356 .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "/test")) 357 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)); 358 assertVisible(QUERIES_NOTHING_RECEIVES_URI, QUERIES_NOTHING_PERM); 359 } 360 361 @Test startActivityWithUri_canSeePermissionProtectedProvider()362 public void startActivityWithUri_canSeePermissionProtectedProvider() throws Exception { 363 assertNotVisible(QUERIES_NOTHING_RECEIVES_PERM_URI, QUERIES_NOTHING_PERM); 364 365 // send with uri but no grant flags; shouldn't be visible 366 startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_PERM_URI, 367 new Intent(ACTION_JUST_FINISH) 368 .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "2/test"))); 369 assertNotVisible(QUERIES_NOTHING_RECEIVES_PERM_URI, QUERIES_NOTHING_PERM); 370 371 // send again with uri bug grant flags now set; should be visible 372 startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_PERM_URI, 373 new Intent(ACTION_JUST_FINISH) 374 .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "2/test")) 375 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)); 376 assertVisible(QUERIES_NOTHING_RECEIVES_PERM_URI, QUERIES_NOTHING_PERM); 377 } 378 379 @Test startActivityWithUriGrant_cannotSeeProviderAfterUpdated()380 public void startActivityWithUriGrant_cannotSeeProviderAfterUpdated() throws Exception { 381 assertNotVisible(QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI, QUERIES_NOTHING_PERM); 382 383 // send with uri grant flags; should be visible 384 startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, 385 QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI, 386 new Intent(ACTION_JUST_FINISH) 387 .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "3/test")) 388 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)); 389 assertVisible(QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI, QUERIES_NOTHING_PERM); 390 391 // update the package; shouldn't be visible 392 runShellCommand("pm install " + QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI_APK); 393 // Wait until the updating is done 394 AmUtils.waitForBroadcastIdle(); 395 assertNotVisible(QUERIES_NOTHING_RECEIVES_NON_PERSISTABLE_URI, QUERIES_NOTHING_PERM); 396 } 397 398 @Test startActivityWithPersistableUriGrant_canSeeProviderAfterUpdated()399 public void startActivityWithPersistableUriGrant_canSeeProviderAfterUpdated() throws Exception { 400 assertNotVisible(QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI, QUERIES_NOTHING_PERM); 401 402 // send with persistable uri grant flags; should be visible 403 startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, 404 QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI, 405 new Intent(ACTION_TAKE_PERSISTABLE_URI_PERMISSION) 406 .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "3/test")) 407 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 408 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); 409 assertVisible(QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI, QUERIES_NOTHING_PERM); 410 411 // update the package; should be still visible 412 runShellCommand("pm install " + QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI_APK); 413 // Wait until the updating is done 414 AmUtils.waitForBroadcastIdle(); 415 assertVisible(QUERIES_NOTHING_RECEIVES_PERSISTABLE_URI, QUERIES_NOTHING_PERM); 416 } 417 startExplicitActivityWithIntent( String sourcePackageName, String targetPackageName, Intent intent)418 private void startExplicitActivityWithIntent( 419 String sourcePackageName, String targetPackageName, Intent intent) throws Exception { 420 sendCommandBlocking(sourcePackageName, targetPackageName, 421 intent.setClassName(targetPackageName, ACTIVITY_CLASS_TEST), 422 ACTION_START_DIRECTLY); 423 } 424 425 @Test queriesNothing_cannotSeeNonForceQueryable()426 public void queriesNothing_cannotSeeNonForceQueryable() throws Exception { 427 assertNotVisible(QUERIES_NOTHING, TARGET_NO_API); 428 assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS); 429 } 430 431 @Test queriesNothingTargetsQ_canSeeAll()432 public void queriesNothingTargetsQ_canSeeAll() throws Exception { 433 assertVisible(QUERIES_NOTHING_Q, TARGET_FORCEQUERYABLE); 434 assertVisible(QUERIES_NOTHING_Q, TARGET_NO_API); 435 assertVisible(QUERIES_NOTHING_Q, TARGET_FILTERS); 436 } 437 438 @Test queriesNothingHasPermission_canSeeAll()439 public void queriesNothingHasPermission_canSeeAll() throws Exception { 440 assertVisible(QUERIES_NOTHING_PERM, TARGET_FORCEQUERYABLE); 441 assertVisible(QUERIES_NOTHING_PERM, TARGET_NO_API); 442 assertVisible(QUERIES_NOTHING_PERM, TARGET_FILTERS); 443 } 444 445 @Test queriesNothing_cannotSeeFilters()446 public void queriesNothing_cannotSeeFilters() throws Exception { 447 assertNotQueryable(QUERIES_NOTHING, TARGET_FILTERS, 448 ACTION_MANIFEST_ACTIVITY, this::queryIntentActivities); 449 assertNotQueryable(QUERIES_NOTHING, TARGET_FILTERS, 450 ACTION_MANIFEST_SERVICE, this::queryIntentServices); 451 assertNotQueryable(QUERIES_NOTHING, TARGET_FILTERS, 452 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders); 453 } 454 455 @Test queriesActivityAction_canSeeFilters()456 public void queriesActivityAction_canSeeFilters() throws Exception { 457 assertQueryable(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS, 458 ACTION_MANIFEST_ACTIVITY, this::queryIntentActivities); 459 assertQueryable(QUERIES_SERVICE_ACTION, TARGET_FILTERS, 460 ACTION_MANIFEST_SERVICE, this::queryIntentServices); 461 assertQueryable(QUERIES_PROVIDER_AUTH, TARGET_FILTERS, 462 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders); 463 assertQueryable(QUERIES_PROVIDER_ACTION, TARGET_FILTERS, 464 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders); 465 } 466 467 @Test queriesNothingHasPermission_canSeeFilters()468 public void queriesNothingHasPermission_canSeeFilters() throws Exception { 469 assertQueryable(QUERIES_NOTHING_PERM, TARGET_FILTERS, 470 ACTION_MANIFEST_ACTIVITY, this::queryIntentActivities); 471 assertQueryable(QUERIES_NOTHING_PERM, TARGET_FILTERS, 472 ACTION_MANIFEST_SERVICE, this::queryIntentServices); 473 assertQueryable(QUERIES_NOTHING_PERM, TARGET_FILTERS, 474 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders); 475 } 476 477 @Test queriesSomething_cannotSeeNoApi()478 public void queriesSomething_cannotSeeNoApi() throws Exception { 479 assertNotVisible(QUERIES_ACTIVITY_ACTION, TARGET_NO_API); 480 assertNotVisible(QUERIES_SERVICE_ACTION, TARGET_NO_API); 481 assertNotVisible(QUERIES_PROVIDER_AUTH, TARGET_NO_API); 482 assertNotVisible(QUERIES_PROVIDER_ACTION, TARGET_NO_API); 483 } 484 485 @Test queriesActivityAction_canSeeTarget()486 public void queriesActivityAction_canSeeTarget() throws Exception { 487 assertVisible(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS); 488 } 489 490 @Test queriesServiceAction_canSeeTarget()491 public void queriesServiceAction_canSeeTarget() throws Exception { 492 assertVisible(QUERIES_SERVICE_ACTION, TARGET_FILTERS); 493 } 494 495 @Test queriesWildcardAction_canSeeTargets()496 public void queriesWildcardAction_canSeeTargets() throws Exception { 497 assertVisible(QUERIES_WILDCARD_ACTION, TARGET_FILTERS); 498 } 499 500 @Test queriesProviderAuthority_canSeeTarget()501 public void queriesProviderAuthority_canSeeTarget() throws Exception { 502 assertVisible(QUERIES_PROVIDER_AUTH, TARGET_FILTERS); 503 } 504 505 @Test queriesProviderAction_canSeeTarget()506 public void queriesProviderAction_canSeeTarget() throws Exception { 507 assertVisible(QUERIES_PROVIDER_ACTION, TARGET_FILTERS); 508 } 509 510 @Test queriesActivityAction_cannotSeeUnexportedTarget()511 public void queriesActivityAction_cannotSeeUnexportedTarget() throws Exception { 512 assertNotVisible(QUERIES_UNEXPORTED_ACTIVITY_ACTION, TARGET_FILTERS); 513 } 514 515 @Test queriesServiceAction_cannotSeeUnexportedTarget()516 public void queriesServiceAction_cannotSeeUnexportedTarget() throws Exception { 517 assertNotVisible(QUERIES_UNEXPORTED_SERVICE_ACTION, TARGET_FILTERS); 518 } 519 520 @Test queriesProviderAuthority_cannotSeeUnexportedTarget()521 public void queriesProviderAuthority_cannotSeeUnexportedTarget() throws Exception { 522 assertNotVisible(QUERIES_UNEXPORTED_PROVIDER_AUTH, TARGET_FILTERS); 523 } 524 525 @Test queriesProviderAction_cannotSeeUnexportedTarget()526 public void queriesProviderAction_cannotSeeUnexportedTarget() throws Exception { 527 assertNotVisible(QUERIES_UNEXPORTED_PROVIDER_ACTION, TARGET_FILTERS); 528 } 529 530 @Test queriesPackage_canSeeTarget()531 public void queriesPackage_canSeeTarget() throws Exception { 532 assertVisible(QUERIES_PACKAGE, TARGET_NO_API); 533 } 534 535 @Test queriesNothing_canSeeInstaller()536 public void queriesNothing_canSeeInstaller() throws Exception { 537 runShellCommand("pm uninstall " + QUERIES_NOTHING_SEES_INSTALLER); 538 runShellCommand("pm install" 539 + " -i " + TARGET_NO_API 540 + " --pkg " + QUERIES_NOTHING_SEES_INSTALLER 541 + " " + QUERIES_NOTHING_SEES_INSTALLER_APK); 542 try { 543 assertVisible(QUERIES_NOTHING_SEES_INSTALLER, TARGET_NO_API); 544 } finally { 545 runShellCommand("pm uninstall " + QUERIES_NOTHING_SEES_INSTALLER); 546 } 547 } 548 549 550 @Test whenStarted_canSeeCaller()551 public void whenStarted_canSeeCaller() throws Exception { 552 // let's first make sure that the target cannot see the caller. 553 assertNotVisible(QUERIES_NOTHING, QUERIES_NOTHING_PERM); 554 // now let's start the target and make sure that it can see the caller as part of that call 555 PackageInfo packageInfo = startForResult(QUERIES_NOTHING_PERM, QUERIES_NOTHING); 556 assertThat(packageInfo, IsNull.notNullValue()); 557 assertThat(packageInfo.packageName, is(QUERIES_NOTHING_PERM)); 558 // and finally let's re-run the last check to make sure that the target can still see the 559 // caller 560 assertVisible(QUERIES_NOTHING, QUERIES_NOTHING_PERM); 561 } 562 563 @Test whenStartedViaIntentSender_canSeeCaller()564 public void whenStartedViaIntentSender_canSeeCaller() throws Exception { 565 // let's first make sure that the target cannot see the caller. 566 assertNotVisible(QUERIES_NOTHING, QUERIES_NOTHING_Q); 567 // now let's start the target via pending intent and make sure that it can see the caller 568 // as part of that call 569 PackageInfo packageInfo = startSenderForResult(QUERIES_NOTHING_Q, QUERIES_NOTHING); 570 assertThat(packageInfo, IsNull.notNullValue()); 571 assertThat(packageInfo.packageName, is(QUERIES_NOTHING_Q)); 572 // and finally let's re-run the last check to make sure that the target can still see the 573 // caller 574 assertVisible(QUERIES_NOTHING, QUERIES_NOTHING_Q); 575 } 576 577 @Test queriesNothing_cannotSeeLibraryPackage()578 public void queriesNothing_cannotSeeLibraryPackage() throws Exception { 579 assertNotVisible(QUERIES_NOTHING, TARGET_SHARED_LIBRARY_PACKAGE); 580 } 581 582 @Test queriesNothingUsesLibrary_canSeeLibraryPackage()583 public void queriesNothingUsesLibrary_canSeeLibraryPackage() throws Exception { 584 assertVisible(QUERIES_NOTHING_USES_LIBRARY, TARGET_SHARED_LIBRARY_PACKAGE); 585 } 586 587 @Test queriesNothing_cannotSeeOptionalLibraryPackage()588 public void queriesNothing_cannotSeeOptionalLibraryPackage() throws Exception { 589 assertNotVisible(QUERIES_NOTHING, TARGET_SHARED_LIBRARY_PACKAGE); 590 } 591 592 @Test queriesNothingUsesOptionalLibrary_canSeeLibraryPackage()593 public void queriesNothingUsesOptionalLibrary_canSeeLibraryPackage() throws Exception { 594 assertVisible(QUERIES_NOTHING_USES_OPTIONAL_LIBRARY, TARGET_SHARED_LIBRARY_PACKAGE); 595 } 596 597 @Test queriesNothing_getPackagesForUid_consistentVisibility()598 public void queriesNothing_getPackagesForUid_consistentVisibility() 599 throws Exception { 600 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 601 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 602 Assert.assertNull(getPackagesForUid(QUERIES_NOTHING, targetSharedUid)); 603 Assert.assertNull(getPackagesForUid(QUERIES_NOTHING, targetUid)); 604 } 605 606 @Test queriesNothingHasPermission_getPackagesForUid_consistentVisibility()607 public void queriesNothingHasPermission_getPackagesForUid_consistentVisibility() 608 throws Exception { 609 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 610 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 611 Assert.assertNotNull(getPackagesForUid(QUERIES_NOTHING_PERM, targetSharedUid)); 612 Assert.assertNotNull(getPackagesForUid(QUERIES_NOTHING_PERM, targetUid)); 613 } 614 615 @Test queriesNothing_getNameForUid_consistentVisibility()616 public void queriesNothing_getNameForUid_consistentVisibility() 617 throws Exception { 618 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 619 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 620 Assert.assertNull(getNameForUid(QUERIES_NOTHING, targetSharedUid)); 621 Assert.assertNull(getNameForUid(QUERIES_NOTHING, targetUid)); 622 } 623 624 @Test queriesNothingHasPermission_getNameForUid_consistentVisibility()625 public void queriesNothingHasPermission_getNameForUid_consistentVisibility() 626 throws Exception { 627 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 628 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 629 Assert.assertNotNull(getNameForUid(QUERIES_NOTHING_PERM, targetSharedUid)); 630 Assert.assertNotNull(getNameForUid(QUERIES_NOTHING_PERM, targetUid)); 631 } 632 633 @Test queriesNothing_getNamesForUids_consistentVisibility()634 public void queriesNothing_getNamesForUids_consistentVisibility() 635 throws Exception { 636 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 637 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 638 Assert.assertNull(getNamesForUids(QUERIES_NOTHING, targetSharedUid)[0]); 639 Assert.assertNull(getNamesForUids(QUERIES_NOTHING, targetUid)[0]); 640 } 641 642 @Test queriesNothingHasPermission_getNamesForUids_consistentVisibility()643 public void queriesNothingHasPermission_getNamesForUids_consistentVisibility() 644 throws Exception { 645 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 646 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 647 Assert.assertNotNull(getNamesForUids(QUERIES_NOTHING_PERM, targetSharedUid)[0]); 648 Assert.assertNotNull(getNamesForUids(QUERIES_NOTHING_PERM, targetUid)[0]); 649 } 650 651 @Test queriesNothing_checkSignatures_consistentVisibility()652 public void queriesNothing_checkSignatures_consistentVisibility() 653 throws Exception { 654 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 655 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 656 Assert.assertEquals(SIGNATURE_UNKNOWN_PACKAGE, 657 checkSignatures(QUERIES_NOTHING, targetSharedUid)); 658 Assert.assertEquals(SIGNATURE_UNKNOWN_PACKAGE, 659 checkSignatures(QUERIES_NOTHING, targetUid)); 660 } 661 662 @Test queriesNothingHasPermission_checkSignatures_consistentVisibility()663 public void queriesNothingHasPermission_checkSignatures_consistentVisibility() 664 throws Exception { 665 final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0); 666 final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0); 667 Assert.assertEquals(SIGNATURE_MATCH, 668 checkSignatures(QUERIES_NOTHING_PERM, targetSharedUid)); 669 Assert.assertEquals(SIGNATURE_MATCH, checkSignatures(QUERIES_NOTHING_PERM, targetUid)); 670 } 671 672 @Test queriesNothing_hasSigningCertificate_consistentVisibility()673 public void queriesNothing_hasSigningCertificate_consistentVisibility() throws Exception { 674 final PackageInfo targetSharedUidInfo = sPm.getPackageInfo(TARGET_SHARED_USER, 675 GET_SIGNING_CERTIFICATES); 676 final PackageInfo targetUidInfo = sPm.getPackageInfo(TARGET_FILTERS, 677 GET_SIGNING_CERTIFICATES); 678 final byte[] targetSharedCert = convertSignaturesToCertificates( 679 targetSharedUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded(); 680 final byte[] targetCert = convertSignaturesToCertificates( 681 targetUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded(); 682 683 Assert.assertFalse( 684 hasSigningCertificate(QUERIES_NOTHING, targetSharedUidInfo.applicationInfo.uid, 685 targetSharedCert)); 686 Assert.assertFalse( 687 hasSigningCertificate(QUERIES_NOTHING, targetUidInfo.applicationInfo.uid, 688 targetCert)); 689 } 690 691 @Test queriesNothingHasPermission_hasSigningCertificate_consistentVisibility()692 public void queriesNothingHasPermission_hasSigningCertificate_consistentVisibility() 693 throws Exception { 694 final PackageInfo targetSharedUidInfo = sPm.getPackageInfo(TARGET_SHARED_USER, 695 GET_SIGNING_CERTIFICATES); 696 final PackageInfo targetUidInfo = sPm.getPackageInfo(TARGET_FILTERS, 697 GET_SIGNING_CERTIFICATES); 698 final byte[] targetSharedCert = convertSignaturesToCertificates( 699 targetSharedUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded(); 700 final byte[] targetCert = convertSignaturesToCertificates( 701 targetUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded(); 702 703 Assert.assertTrue( 704 hasSigningCertificate(QUERIES_NOTHING_PERM, targetSharedUidInfo.applicationInfo.uid, 705 targetSharedCert)); 706 Assert.assertTrue( 707 hasSigningCertificate(QUERIES_NOTHING_PERM, targetUidInfo.applicationInfo.uid, 708 targetCert)); 709 } 710 711 @Test sharedUserMember_canSeeOtherMember()712 public void sharedUserMember_canSeeOtherMember() throws Exception { 713 assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SHARED_USER); 714 } 715 716 @Test queriesPackage_canSeeAllSharedUserMembers()717 public void queriesPackage_canSeeAllSharedUserMembers() throws Exception { 718 // explicitly queries target via manifest 719 assertVisible(QUERIES_PACKAGE, TARGET_SHARED_USER); 720 // implicitly granted visibility to other member of shared user 721 assertVisible(QUERIES_PACKAGE, QUERIES_NOTHING_SHARED_USER); 722 } 723 724 @Test queriesWildcardContacts()725 public void queriesWildcardContacts() throws Exception { 726 assertNotVisible(QUERIES_NOTHING, TARGET_CONTACTS); 727 assertVisible(QUERIES_WILDCARD_CONTACTS, TARGET_CONTACTS); 728 } 729 730 @Test queriesWildcardWeb()731 public void queriesWildcardWeb() throws Exception { 732 assertNotVisible(QUERIES_NOTHING, TARGET_WEB); 733 assertVisible(QUERIES_WILDCARD_BROWSABLE, TARGET_WEB); 734 assertVisible(QUERIES_WILDCARD_WEB, TARGET_WEB); 735 } 736 737 @Test queriesWildcardBrowser()738 public void queriesWildcardBrowser() throws Exception { 739 assertNotVisible(QUERIES_NOTHING, TARGET_BROWSER); 740 assertNotVisible(QUERIES_WILDCARD_BROWSER, TARGET_WEB); 741 assertVisible(QUERIES_WILDCARD_BROWSER, TARGET_BROWSER); 742 assertVisible(QUERIES_WILDCARD_BROWSER, TARGET_BROWSER_WILDCARD); 743 } 744 745 @Test queriesWildcardWeb_canSeePrefixWildcardWeb()746 public void queriesWildcardWeb_canSeePrefixWildcardWeb() throws Exception { 747 assertNotVisible(QUERIES_NOTHING, TARGET_PREFIX_WILDCARD_WEB); 748 assertVisible(QUERIES_WILDCARD_BROWSABLE, TARGET_PREFIX_WILDCARD_WEB); 749 assertVisible(QUERIES_WILDCARD_WEB, TARGET_PREFIX_WILDCARD_WEB); 750 } 751 752 @Test queriesWildcardBrowser_cannotseePrefixWildcardWeb()753 public void queriesWildcardBrowser_cannotseePrefixWildcardWeb() throws Exception { 754 assertNotVisible(QUERIES_NOTHING, TARGET_PREFIX_WILDCARD_WEB); 755 assertNotVisible(QUERIES_WILDCARD_BROWSER, TARGET_PREFIX_WILDCARD_WEB); 756 } 757 758 @Test queriesWildcardEditor()759 public void queriesWildcardEditor() throws Exception { 760 assertNotVisible(QUERIES_NOTHING, TARGET_EDITOR); 761 assertVisible(QUERIES_WILDCARD_EDITOR, TARGET_EDITOR); 762 } 763 764 @Test queriesWildcardShareSheet()765 public void queriesWildcardShareSheet() throws Exception { 766 assertNotVisible(QUERIES_NOTHING, TARGET_SHARE); 767 assertVisible(QUERIES_WILDCARD_SHARE, TARGET_SHARE); 768 } 769 770 @Test queriesNothing_cannotSeeA11yService()771 public void queriesNothing_cannotSeeA11yService() throws Exception { 772 if (!sGlobalFeatureEnabled) return; 773 final String[] result = getInstalledAccessibilityServices(QUERIES_NOTHING); 774 assertThat(result, not(hasItemInArray(TARGET_FILTERS))); 775 } 776 777 @Test queriesNothingHasPermission_canSeeA11yService()778 public void queriesNothingHasPermission_canSeeA11yService() throws Exception { 779 if (!sGlobalFeatureEnabled) return; 780 final String[] result = getInstalledAccessibilityServices(QUERIES_NOTHING_PERM); 781 assertThat(QUERIES_NOTHING_PERM + " should be able to see " + TARGET_FILTERS, 782 result, hasItemInArray(TARGET_FILTERS)); 783 } 784 assertVisible(String sourcePackageName, String targetPackageName)785 private void assertVisible(String sourcePackageName, String targetPackageName) 786 throws Exception { 787 if (!sGlobalFeatureEnabled) return; 788 Assert.assertNotNull(sourcePackageName + " should be able to see " + targetPackageName, 789 getPackageInfo(sourcePackageName, targetPackageName)); 790 } 791 792 @Test broadcastAdded_notVisibleDoesNotReceive()793 public void broadcastAdded_notVisibleDoesNotReceive() throws Exception { 794 final Result result = sendCommand(QUERIES_NOTHING, TARGET_FILTERS, 795 /* targetUid */ INVALID_UID, /* intentExtra */ null, 796 Constants.ACTION_AWAIT_PACKAGE_ADDED, /* waitForReady */ true); 797 runShellCommand("pm install " + TARGET_FILTERS_APK); 798 try { 799 result.await(); 800 fail(); 801 } catch (MissingBroadcastException e) { 802 // hooray 803 } 804 } 805 806 @Test broadcastAdded_visibleReceives()807 public void broadcastAdded_visibleReceives() throws Exception { 808 final Result result = sendCommand(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS, 809 /* targetUid */ INVALID_UID, /* intentExtra */ null, 810 Constants.ACTION_AWAIT_PACKAGE_ADDED, /* waitForReady */ true); 811 runShellCommand("pm install " + TARGET_FILTERS_APK); 812 try { 813 Assert.assertEquals(TARGET_FILTERS, 814 Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart()); 815 } catch (MissingBroadcastException e) { 816 fail(); 817 } 818 } 819 820 @Test reinstallTarget_broadcastRemoved_notVisibleDoesNotReceive()821 public void reinstallTarget_broadcastRemoved_notVisibleDoesNotReceive() throws Exception { 822 final Result result = sendCommand(QUERIES_NOTHING, TARGET_FILTERS, 823 /* targetUid */ INVALID_UID, /* intentExtra */ null, 824 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true); 825 runShellCommand("pm install " + TARGET_FILTERS_APK); 826 try { 827 result.await(); 828 fail(); 829 } catch (MissingBroadcastException e) { 830 // hooray 831 } 832 } 833 834 @Test reinstallTarget_broadcastRemoved_visibleReceives()835 public void reinstallTarget_broadcastRemoved_visibleReceives() throws Exception { 836 final Result result = sendCommand(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS, 837 /* targetUid */ INVALID_UID, /* intentExtra */ null, 838 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true); 839 runShellCommand("pm install " + TARGET_FILTERS_APK); 840 try { 841 Assert.assertEquals(TARGET_FILTERS, 842 Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart()); 843 } catch (MissingBroadcastException e) { 844 fail(); 845 } 846 } 847 848 @Test uninstallTarget_broadcastRemoved_notVisibleDoesNotReceive()849 public void uninstallTarget_broadcastRemoved_notVisibleDoesNotReceive() throws Exception { 850 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 851 final Result result = sendCommand(QUERIES_NOTHING, TARGET_STUB, 852 /* targetUid */ INVALID_UID, /* intentExtra */ null, 853 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true); 854 runShellCommand("pm uninstall " + TARGET_STUB); 855 try { 856 result.await(); 857 fail(); 858 } catch (MissingBroadcastException e) { 859 // hooray 860 } 861 } 862 863 @Test uninstallTarget_broadcastRemoved_visibleReceives()864 public void uninstallTarget_broadcastRemoved_visibleReceives() throws Exception { 865 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 866 final Result result = sendCommand(QUERIES_NOTHING_PERM, TARGET_STUB, 867 /* targetUid */ INVALID_UID, /* intentExtra */ null, 868 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true); 869 runShellCommand("pm uninstall " + TARGET_STUB); 870 try { 871 Assert.assertEquals(TARGET_STUB, 872 Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart()); 873 } catch (MissingBroadcastException e) { 874 fail(); 875 } 876 } 877 878 @Test uninstallTarget_broadcastFullyRemoved_notVisibleDoesNotReceive()879 public void uninstallTarget_broadcastFullyRemoved_notVisibleDoesNotReceive() throws Exception { 880 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 881 final Result result = sendCommand(QUERIES_NOTHING, TARGET_STUB, 882 /* targetUid */ INVALID_UID, /* intentExtra */ null, 883 Constants.ACTION_AWAIT_PACKAGE_FULLY_REMOVED, /* waitForReady */ true); 884 runShellCommand("pm uninstall " + TARGET_STUB); 885 try { 886 result.await(); 887 fail(); 888 } catch (MissingBroadcastException e) { 889 // hooray 890 } 891 } 892 893 @Test uninstallTarget_broadcastFullyRemoved_visibleReceives()894 public void uninstallTarget_broadcastFullyRemoved_visibleReceives() throws Exception { 895 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 896 final Result result = sendCommand(QUERIES_NOTHING_PERM, TARGET_STUB, 897 /* targetUid */ INVALID_UID, /* intentExtra */ null, 898 Constants.ACTION_AWAIT_PACKAGE_FULLY_REMOVED, /* waitForReady */ true); 899 runShellCommand("pm uninstall " + TARGET_STUB); 900 try { 901 Assert.assertEquals(TARGET_STUB, 902 Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart()); 903 } catch (MissingBroadcastException e) { 904 fail(); 905 } 906 } 907 908 @Test clearTargetData_broadcastDataCleared_notVisibleDoesNotReceive()909 public void clearTargetData_broadcastDataCleared_notVisibleDoesNotReceive() throws Exception { 910 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 911 final Result result = sendCommand(QUERIES_NOTHING, TARGET_STUB, 912 /* targetUid */ INVALID_UID, /* intentExtra */ null, 913 Constants.ACTION_AWAIT_PACKAGE_DATA_CLEARED, /* waitForReady */ true); 914 runShellCommand("pm clear --user cur " + TARGET_STUB); 915 try { 916 result.await(); 917 fail(); 918 } catch (MissingBroadcastException e) { 919 // hooray 920 } 921 } 922 923 @Test clearTargetData_broadcastDataCleared_visibleReceives()924 public void clearTargetData_broadcastDataCleared_visibleReceives() throws Exception { 925 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 926 final Result result = sendCommand(QUERIES_NOTHING_PERM, TARGET_STUB, 927 /* targetUid */ INVALID_UID, /* intentExtra */ null, 928 Constants.ACTION_AWAIT_PACKAGE_DATA_CLEARED, /* waitForReady */ true); 929 runShellCommand("pm clear --user cur " + TARGET_STUB); 930 try { 931 Assert.assertEquals(TARGET_STUB, 932 Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart()); 933 } catch (MissingBroadcastException e) { 934 fail(); 935 } 936 } 937 938 @Test broadcastSuspended_visibleReceives()939 public void broadcastSuspended_visibleReceives() throws Exception { 940 assertBroadcastSuspendedVisible(QUERIES_PACKAGE, 941 Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER), 942 Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER)); 943 } 944 945 @Test broadcastSuspended_notVisibleDoesNotReceive()946 public void broadcastSuspended_notVisibleDoesNotReceive() throws Exception { 947 assertBroadcastSuspendedVisible(QUERIES_NOTHING, 948 Arrays.asList(), 949 Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER)); 950 } 951 952 @Test broadcastSuspended_visibleReceivesAndNotVisibleDoesNotReceive()953 public void broadcastSuspended_visibleReceivesAndNotVisibleDoesNotReceive() throws Exception { 954 assertBroadcastSuspendedVisible(QUERIES_ACTIVITY_ACTION, 955 Arrays.asList(TARGET_FILTERS), 956 Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 957 } 958 959 @Test launcherAppsCallback_added_notVisibleNotReceives()960 public void launcherAppsCallback_added_notVisibleNotReceives() throws Exception { 961 ensurePackageIsNotInstalled(TARGET_STUB); 962 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING, 963 CALLBACK_EVENT_PACKAGE_ADDED); 964 965 runShellCommand("pm install " + TARGET_STUB_APK); 966 final Bundle response = result.await(); 967 968 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID)); 969 assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray()); 970 } 971 972 @Test launcherAppsCallback_added_visibleReceives()973 public void launcherAppsCallback_added_visibleReceives() throws Exception { 974 ensurePackageIsNotInstalled(TARGET_STUB); 975 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING_PERM, 976 CALLBACK_EVENT_PACKAGE_ADDED); 977 978 runShellCommand("pm install " + TARGET_STUB_APK); 979 final Bundle response = result.await(); 980 981 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGE_ADDED)); 982 assertThat(response.getStringArray(EXTRA_PACKAGES), 983 arrayContainingInAnyOrder(new String[]{TARGET_STUB})); 984 } 985 986 @Test launcherAppsCallback_removed_notVisibleNotReceives()987 public void launcherAppsCallback_removed_notVisibleNotReceives() throws Exception { 988 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 989 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING, 990 CALLBACK_EVENT_PACKAGE_REMOVED); 991 992 runShellCommand("pm uninstall " + TARGET_STUB); 993 final Bundle response = result.await(); 994 995 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID)); 996 assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray()); 997 } 998 999 @Test launcherAppsCallback_removed_visibleReceives()1000 public void launcherAppsCallback_removed_visibleReceives() throws Exception { 1001 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 1002 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING_PERM, 1003 CALLBACK_EVENT_PACKAGE_REMOVED); 1004 1005 runShellCommand("pm uninstall " + TARGET_STUB); 1006 final Bundle response = result.await(); 1007 1008 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGE_REMOVED)); 1009 assertThat(response.getStringArray(EXTRA_PACKAGES), 1010 arrayContainingInAnyOrder(new String[]{TARGET_STUB})); 1011 } 1012 1013 @Test launcherAppsCallback_changed_notVisibleNotReceives()1014 public void launcherAppsCallback_changed_notVisibleNotReceives() throws Exception { 1015 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING, 1016 CALLBACK_EVENT_PACKAGE_CHANGED); 1017 1018 runShellCommand("pm install " + TARGET_FILTERS_APK); 1019 final Bundle response = result.await(); 1020 1021 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID)); 1022 assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray()); 1023 } 1024 1025 @Test launcherAppsCallback_changed_visibleReceives()1026 public void launcherAppsCallback_changed_visibleReceives() throws Exception { 1027 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING_PERM, 1028 CALLBACK_EVENT_PACKAGE_CHANGED); 1029 1030 runShellCommand("pm install " + TARGET_FILTERS_APK); 1031 final Bundle response = result.await(); 1032 1033 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGE_CHANGED)); 1034 assertThat(response.getStringArray(EXTRA_PACKAGES), 1035 arrayContainingInAnyOrder(new String[]{TARGET_FILTERS})); 1036 } 1037 1038 @Test launcherAppsCallback_suspended_notVisibleNotReceives()1039 public void launcherAppsCallback_suspended_notVisibleNotReceives() throws Exception { 1040 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING, 1041 CALLBACK_EVENT_PACKAGES_SUSPENDED); 1042 1043 try { 1044 setPackagesSuspended(/* suspend */ true, 1045 Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1046 final Bundle response = result.await(); 1047 1048 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID)); 1049 assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray()); 1050 } finally { 1051 setPackagesSuspended(/* suspend */ false, 1052 Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1053 } 1054 } 1055 1056 @Test launcherAppsCallback_suspended_visibleReceives()1057 public void launcherAppsCallback_suspended_visibleReceives() throws Exception { 1058 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_ACTIVITY_ACTION, 1059 CALLBACK_EVENT_PACKAGES_SUSPENDED); 1060 1061 try { 1062 setPackagesSuspended(/* suspend */ true, 1063 Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1064 final Bundle response = result.await(); 1065 1066 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGES_SUSPENDED)); 1067 assertThat(response.getStringArray(EXTRA_PACKAGES), 1068 arrayContainingInAnyOrder(new String[]{TARGET_FILTERS})); 1069 } finally { 1070 setPackagesSuspended(/* suspend */ false, 1071 Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1072 } 1073 } 1074 1075 @Test launcherAppsCallback_unsuspended_notVisibleNotReceives()1076 public void launcherAppsCallback_unsuspended_notVisibleNotReceives() throws Exception { 1077 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING, 1078 CALLBACK_EVENT_PACKAGES_UNSUSPENDED); 1079 1080 setPackagesSuspended(/* suspend */ false, Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1081 final Bundle response = result.await(); 1082 1083 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID)); 1084 assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray()); 1085 } 1086 1087 @Test launcherAppsCallback_unsuspended_visibleReceives()1088 public void launcherAppsCallback_unsuspended_visibleReceives() throws Exception { 1089 setPackagesSuspended(/* suspend */ true, Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1090 1091 final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_ACTIVITY_ACTION, 1092 CALLBACK_EVENT_PACKAGES_UNSUSPENDED); 1093 1094 setPackagesSuspended(/* suspend */ false, Arrays.asList(TARGET_NO_API, TARGET_FILTERS)); 1095 final Bundle response = result.await(); 1096 1097 assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGES_UNSUSPENDED)); 1098 assertThat(response.getStringArray(EXTRA_PACKAGES), 1099 arrayContainingInAnyOrder(new String[]{TARGET_FILTERS})); 1100 } 1101 1102 @Test launcherAppsSessionCallback_queriesNothing_cannotSeeSession()1103 public void launcherAppsSessionCallback_queriesNothing_cannotSeeSession() throws Exception { 1104 try { 1105 adoptShellPermissions(); 1106 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1107 .createSession(); 1108 final Result result = sendCommandAndWaitForLauncherAppsSessionCallback( 1109 QUERIES_NOTHING, sessionId); 1110 commitSession(sessionId); 1111 final Bundle response = result.await(); 1112 assertThat(response.getInt(EXTRA_ID), equalTo(SessionInfo.INVALID_ID)); 1113 } finally { 1114 runShellCommand("pm uninstall " + TestApp.A); 1115 dropShellPermissions(); 1116 } 1117 } 1118 1119 @Test launcherAppsSessionCallback_queriesNothingHasPermission_canSeeSession()1120 public void launcherAppsSessionCallback_queriesNothingHasPermission_canSeeSession() 1121 throws Exception { 1122 try { 1123 adoptShellPermissions(); 1124 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1125 .createSession(); 1126 final Result result = sendCommandAndWaitForLauncherAppsSessionCallback( 1127 QUERIES_NOTHING_PERM, sessionId); 1128 commitSession(sessionId); 1129 final Bundle response = result.await(); 1130 assertThat(response.getInt(EXTRA_ID), equalTo(sessionId)); 1131 } finally { 1132 runShellCommand("pm uninstall " + TestApp.A); 1133 dropShellPermissions(); 1134 } 1135 } 1136 1137 @Test launcherAppsSessionCallback_queriesPackage_canSeeSession()1138 public void launcherAppsSessionCallback_queriesPackage_canSeeSession() 1139 throws Exception { 1140 try { 1141 adoptShellPermissions(); 1142 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1143 .createSession(); 1144 final Result result = sendCommandAndWaitForLauncherAppsSessionCallback( 1145 QUERIES_PACKAGE, sessionId); 1146 commitSession(sessionId); 1147 final Bundle response = result.await(); 1148 assertThat(response.getInt(EXTRA_ID), equalTo(sessionId)); 1149 } finally { 1150 runShellCommand("pm uninstall " + TestApp.A); 1151 dropShellPermissions(); 1152 } 1153 } 1154 1155 @Test launcherAppsSessionCallback_queriesNothingTargetsQ_canSeeSession()1156 public void launcherAppsSessionCallback_queriesNothingTargetsQ_canSeeSession() 1157 throws Exception { 1158 try { 1159 adoptShellPermissions(); 1160 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1161 .createSession(); 1162 final Result result = sendCommandAndWaitForLauncherAppsSessionCallback( 1163 QUERIES_NOTHING_Q, sessionId); 1164 commitSession(sessionId); 1165 final Bundle response = result.await(); 1166 assertThat(response.getInt(EXTRA_ID), equalTo(sessionId)); 1167 } finally { 1168 runShellCommand("pm uninstall " + TestApp.A); 1169 dropShellPermissions(); 1170 } 1171 } 1172 1173 @Test launcherAppsSessionCallback_sessionOwner_canSeeSession()1174 public void launcherAppsSessionCallback_sessionOwner_canSeeSession() throws Exception { 1175 try { 1176 adoptShellPermissions(); 1177 final CountDownLatch countDownLatch = new CountDownLatch(1); 1178 final int expectedSessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1179 .createSession(); 1180 final Context context = InstrumentationRegistry 1181 .getInstrumentation() 1182 .getContext(); 1183 final LauncherApps launcherApps = context.getSystemService(LauncherApps.class); 1184 final PackageInstaller.SessionCallback 1185 sessionCallback = new PackageInstaller.SessionCallback() { 1186 1187 @Override 1188 public void onCreated(int sessionId) { 1189 // No-op 1190 } 1191 1192 @Override 1193 public void onBadgingChanged(int sessionId) { 1194 // No-op 1195 } 1196 1197 @Override 1198 public void onActiveChanged(int sessionId, boolean active) { 1199 // No-op 1200 } 1201 1202 @Override 1203 public void onProgressChanged(int sessionId, float progress) { 1204 // No-op 1205 } 1206 1207 @Override 1208 public void onFinished(int sessionId, boolean success) { 1209 if (sessionId != expectedSessionId) { 1210 return; 1211 } 1212 1213 launcherApps.unregisterPackageInstallerSessionCallback(this); 1214 countDownLatch.countDown(); 1215 } 1216 }; 1217 1218 launcherApps.registerPackageInstallerSessionCallback(context.getMainExecutor(), 1219 sessionCallback); 1220 1221 commitSession(expectedSessionId); 1222 assertTrue(countDownLatch.await(5, TimeUnit.SECONDS)); 1223 } finally { 1224 runShellCommand("pm uninstall " + TestApp.A); 1225 dropShellPermissions(); 1226 } 1227 } 1228 sendCommandAndWaitForLauncherAppsSessionCallback(String sourcePackageName, int expectedSessionId)1229 private Result sendCommandAndWaitForLauncherAppsSessionCallback(String sourcePackageName, 1230 int expectedSessionId) throws Exception { 1231 final Bundle extra = new Bundle(); 1232 extra.putInt(EXTRA_ID, expectedSessionId); 1233 final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null, 1234 /* targetUid */ INVALID_UID, extra, ACTION_AWAIT_LAUNCHER_APPS_SESSION_CALLBACK, 1235 /* waitForReady */ true); 1236 return result; 1237 } 1238 1239 @Test launcherApps_getAllPkgInstallerSessions_queriesNothing_cannotSeeSessions()1240 public void launcherApps_getAllPkgInstallerSessions_queriesNothing_cannotSeeSessions() 1241 throws Exception { 1242 try { 1243 adoptShellPermissions(); 1244 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1245 .createSession(); 1246 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS, 1247 QUERIES_NOTHING, SessionInfo.INVALID_ID); 1248 assertSessionNotVisible(sessionIds, sessionId); 1249 } finally { 1250 cleanUpSessions(); 1251 dropShellPermissions(); 1252 } 1253 } 1254 1255 @Test launcherApps_getAllPkgInstallerSessions_queriesNothingHasPermission_canSeeSessions()1256 public void launcherApps_getAllPkgInstallerSessions_queriesNothingHasPermission_canSeeSessions() 1257 throws Exception { 1258 try { 1259 adoptShellPermissions(); 1260 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1261 .createSession(); 1262 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS, 1263 QUERIES_NOTHING_PERM, SessionInfo.INVALID_ID); 1264 assertSessionVisible(sessionIds, sessionId); 1265 } finally { 1266 cleanUpSessions(); 1267 dropShellPermissions(); 1268 } 1269 } 1270 1271 @Test launcherApps_getAllPkgInstallerSessions_queriesPackage_canSeeSessions()1272 public void launcherApps_getAllPkgInstallerSessions_queriesPackage_canSeeSessions() 1273 throws Exception { 1274 try { 1275 adoptShellPermissions(); 1276 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1277 .createSession(); 1278 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS, 1279 QUERIES_PACKAGE, SessionInfo.INVALID_ID); 1280 assertSessionVisible(sessionIds, sessionId); 1281 } finally { 1282 cleanUpSessions(); 1283 dropShellPermissions(); 1284 } 1285 } 1286 1287 @Test launcherApps_getAllPkgInstallerSessions_queriesNothingTargetsQ_canSeeSessions()1288 public void launcherApps_getAllPkgInstallerSessions_queriesNothingTargetsQ_canSeeSessions() 1289 throws Exception { 1290 try { 1291 adoptShellPermissions(); 1292 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1293 .createSession(); 1294 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS, 1295 QUERIES_NOTHING_Q, SessionInfo.INVALID_ID); 1296 assertSessionVisible(sessionIds, sessionId); 1297 } finally { 1298 cleanUpSessions(); 1299 dropShellPermissions(); 1300 } 1301 } 1302 1303 @Test launcherApps_getAllPkgInstallerSessions_sessionOwner_canSeeSessions()1304 public void launcherApps_getAllPkgInstallerSessions_sessionOwner_canSeeSessions() 1305 throws Exception { 1306 try { 1307 adoptShellPermissions(); 1308 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1309 .createSession(); 1310 final LauncherApps launcherApps = InstrumentationRegistry 1311 .getInstrumentation() 1312 .getContext() 1313 .getSystemService(LauncherApps.class); 1314 final Integer[] sessionIds = launcherApps.getAllPackageInstallerSessions().stream() 1315 .map(i -> i.getSessionId()) 1316 .distinct() 1317 .toArray(Integer[]::new); 1318 assertSessionVisible(sessionIds, sessionId); 1319 } finally { 1320 cleanUpSessions(); 1321 dropShellPermissions(); 1322 } 1323 } 1324 1325 @Test packageInstaller_getSessionInfo_queriesNothing_cannotSeeSession()1326 public void packageInstaller_getSessionInfo_queriesNothing_cannotSeeSession() 1327 throws Exception { 1328 try { 1329 adoptShellPermissions(); 1330 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1331 .createSession(); 1332 final Integer[] sessionIds = getSessionInfos(ACTION_GET_SESSION_INFO, 1333 QUERIES_NOTHING, sessionId); 1334 assertSessionNotVisible(sessionIds, sessionId); 1335 } finally { 1336 cleanUpSessions(); 1337 dropShellPermissions(); 1338 } 1339 } 1340 1341 @Test packageInstaller_getSessionInfo_queriesNothingHasPermission_canSeeSession()1342 public void packageInstaller_getSessionInfo_queriesNothingHasPermission_canSeeSession() 1343 throws Exception { 1344 try { 1345 adoptShellPermissions(); 1346 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1347 .createSession(); 1348 final Integer[] sessionIds = getSessionInfos(ACTION_GET_SESSION_INFO, 1349 QUERIES_NOTHING_PERM, sessionId); 1350 assertSessionVisible(sessionIds, sessionId); 1351 } finally { 1352 cleanUpSessions(); 1353 dropShellPermissions(); 1354 } 1355 } 1356 1357 @Test packageInstaller_getSessionInfo_queriesPackage_canSeeSession()1358 public void packageInstaller_getSessionInfo_queriesPackage_canSeeSession() 1359 throws Exception { 1360 try { 1361 adoptShellPermissions(); 1362 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1363 .createSession(); 1364 final Integer[] sessionIds = getSessionInfos(ACTION_GET_SESSION_INFO, 1365 QUERIES_PACKAGE, sessionId); 1366 assertSessionVisible(sessionIds, sessionId); 1367 } finally { 1368 cleanUpSessions(); 1369 dropShellPermissions(); 1370 } 1371 } 1372 1373 @Test packageInstaller_getSessionInfo_queriesNothingTargetsQ_canSeeSession()1374 public void packageInstaller_getSessionInfo_queriesNothingTargetsQ_canSeeSession() 1375 throws Exception { 1376 try { 1377 adoptShellPermissions(); 1378 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1379 .createSession(); 1380 final Integer[] sessionIds = getSessionInfos(ACTION_GET_SESSION_INFO, 1381 QUERIES_NOTHING_Q, sessionId); 1382 assertSessionVisible(sessionIds, sessionId); 1383 } finally { 1384 cleanUpSessions(); 1385 dropShellPermissions(); 1386 } 1387 } 1388 1389 @Test packageInstaller_getSessionInfo_sessionOwner_canSeeSession()1390 public void packageInstaller_getSessionInfo_sessionOwner_canSeeSession() 1391 throws Exception { 1392 try { 1393 adoptShellPermissions(); 1394 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1395 .createSession(); 1396 final PackageInstaller installer = InstrumentationRegistry 1397 .getInstrumentation() 1398 .getContext() 1399 .getPackageManager() 1400 .getPackageInstaller(); 1401 final SessionInfo info = installer.getSessionInfo(sessionId); 1402 assertThat(info, IsNull.notNullValue()); 1403 } finally { 1404 cleanUpSessions(); 1405 dropShellPermissions(); 1406 } 1407 } 1408 1409 @Test packageInstaller_getStagedSessions_queriesNothing_cannotSeeSession()1410 public void packageInstaller_getStagedSessions_queriesNothing_cannotSeeSession() 1411 throws Exception { 1412 try { 1413 adoptShellPermissions(); 1414 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A).setStaged() 1415 .createSession(); 1416 final Integer[] sessionIds = getSessionInfos(ACTION_GET_STAGED_SESSIONS, 1417 QUERIES_NOTHING, sessionId); 1418 assertSessionNotVisible(sessionIds, sessionId); 1419 } finally { 1420 cleanUpSessions(); 1421 dropShellPermissions(); 1422 } 1423 } 1424 1425 @Test packageInstaller_getStagedSessions_queriesNothingHasPermission_canSeeSession()1426 public void packageInstaller_getStagedSessions_queriesNothingHasPermission_canSeeSession() 1427 throws Exception { 1428 try { 1429 adoptShellPermissions(); 1430 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A).setStaged() 1431 .createSession(); 1432 final Integer[] sessionIds = getSessionInfos(ACTION_GET_STAGED_SESSIONS, 1433 QUERIES_NOTHING_PERM, sessionId); 1434 assertSessionVisible(sessionIds, sessionId); 1435 } finally { 1436 cleanUpSessions(); 1437 dropShellPermissions(); 1438 } 1439 } 1440 1441 @Test packageInstaller_getStagedSessions_queriesPackage_canSeeSession()1442 public void packageInstaller_getStagedSessions_queriesPackage_canSeeSession() 1443 throws Exception { 1444 try { 1445 adoptShellPermissions(); 1446 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A).setStaged() 1447 .createSession(); 1448 final Integer[] sessionIds = getSessionInfos(ACTION_GET_STAGED_SESSIONS, 1449 QUERIES_PACKAGE, sessionId); 1450 assertSessionVisible(sessionIds, sessionId); 1451 } finally { 1452 cleanUpSessions(); 1453 dropShellPermissions(); 1454 } 1455 } 1456 1457 @Test packageInstaller_getStagedSessions_queriesNothingTargetsQ_canSeeSession()1458 public void packageInstaller_getStagedSessions_queriesNothingTargetsQ_canSeeSession() 1459 throws Exception { 1460 try { 1461 adoptShellPermissions(); 1462 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A).setStaged() 1463 .createSession(); 1464 final Integer[] sessionIds = getSessionInfos(ACTION_GET_STAGED_SESSIONS, 1465 QUERIES_NOTHING_Q, sessionId); 1466 assertSessionVisible(sessionIds, sessionId); 1467 } finally { 1468 cleanUpSessions(); 1469 dropShellPermissions(); 1470 } 1471 } 1472 1473 @Test packageInstaller_getStagedSessions_sessionOwner_canSeeSession()1474 public void packageInstaller_getStagedSessions_sessionOwner_canSeeSession() 1475 throws Exception { 1476 try { 1477 adoptShellPermissions(); 1478 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A).setStaged() 1479 .createSession(); 1480 final PackageInstaller installer = InstrumentationRegistry 1481 .getInstrumentation() 1482 .getContext() 1483 .getPackageManager() 1484 .getPackageInstaller(); 1485 final Integer[] sessionIds = installer.getStagedSessions().stream() 1486 .map(i -> i.getSessionId()) 1487 .distinct() 1488 .toArray(Integer[]::new); 1489 assertSessionVisible(sessionIds, sessionId); 1490 } finally { 1491 cleanUpSessions(); 1492 dropShellPermissions(); 1493 } 1494 } 1495 1496 @Test packageInstaller_getAllSessions_queriesNothing_cannotSeeSession()1497 public void packageInstaller_getAllSessions_queriesNothing_cannotSeeSession() 1498 throws Exception { 1499 try { 1500 adoptShellPermissions(); 1501 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1502 .createSession(); 1503 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_SESSIONS, 1504 QUERIES_NOTHING, sessionId); 1505 assertSessionNotVisible(sessionIds, sessionId); 1506 } finally { 1507 cleanUpSessions(); 1508 dropShellPermissions(); 1509 } 1510 } 1511 1512 @Test packageInstaller_getAllSessions_queriesNothingHasPermission_canSeeSession()1513 public void packageInstaller_getAllSessions_queriesNothingHasPermission_canSeeSession() 1514 throws Exception { 1515 try { 1516 adoptShellPermissions(); 1517 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1518 .createSession(); 1519 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_SESSIONS, 1520 QUERIES_NOTHING_PERM, sessionId); 1521 assertSessionVisible(sessionIds, sessionId); 1522 } finally { 1523 cleanUpSessions(); 1524 dropShellPermissions(); 1525 } 1526 } 1527 1528 @Test packageInstaller_getAllSessions_queriesPackage_canSeeSession()1529 public void packageInstaller_getAllSessions_queriesPackage_canSeeSession() 1530 throws Exception { 1531 try { 1532 adoptShellPermissions(); 1533 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1534 .createSession(); 1535 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_SESSIONS, 1536 QUERIES_PACKAGE, sessionId); 1537 assertSessionVisible(sessionIds, sessionId); 1538 } finally { 1539 cleanUpSessions(); 1540 dropShellPermissions(); 1541 } 1542 } 1543 1544 @Test packageInstaller_getAllSessions_queriesNothingTargetsQ_canSeeSession()1545 public void packageInstaller_getAllSessions_queriesNothingTargetsQ_canSeeSession() 1546 throws Exception { 1547 try { 1548 adoptShellPermissions(); 1549 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1550 .createSession(); 1551 final Integer[] sessionIds = getSessionInfos(ACTION_GET_ALL_SESSIONS, 1552 QUERIES_NOTHING_Q, sessionId); 1553 assertSessionVisible(sessionIds, sessionId); 1554 } finally { 1555 cleanUpSessions(); 1556 dropShellPermissions(); 1557 } 1558 } 1559 1560 @Test packageInstaller_getAllSessions_sessionOwner_canSeeSession()1561 public void packageInstaller_getAllSessions_sessionOwner_canSeeSession() 1562 throws Exception { 1563 try { 1564 adoptShellPermissions(); 1565 final int sessionId = Install.single(TestApp.A1).setPackageName(TestApp.A) 1566 .createSession(); 1567 final PackageInstaller installer = InstrumentationRegistry 1568 .getInstrumentation() 1569 .getContext() 1570 .getPackageManager() 1571 .getPackageInstaller(); 1572 final Integer[] sessionIds = installer.getAllSessions().stream() 1573 .map(i -> i.getSessionId()) 1574 .distinct() 1575 .toArray(Integer[]::new); 1576 assertSessionVisible(sessionIds, sessionId); 1577 } finally { 1578 cleanUpSessions(); 1579 dropShellPermissions(); 1580 } 1581 } 1582 getSessionInfos(String action, String sourcePackageName, int sessionId)1583 private Integer[] getSessionInfos(String action, String sourcePackageName, int sessionId) 1584 throws Exception { 1585 final Bundle extraData = new Bundle(); 1586 extraData.putInt(EXTRA_ID, sessionId); 1587 final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null, 1588 extraData, action); 1589 final List<Parcelable> parcelables = response.getParcelableArrayList( 1590 Intent.EXTRA_RETURN_RESULT); 1591 return parcelables.stream() 1592 .map(i -> (i == null ? SessionInfo.INVALID_ID : ((SessionInfo) i).getSessionId())) 1593 .distinct() 1594 .toArray(Integer[]::new); 1595 } 1596 assertSessionVisible(Integer[] sessionIds, int sessionId)1597 private void assertSessionVisible(Integer[] sessionIds, int sessionId) { 1598 if (!sGlobalFeatureEnabled) { 1599 return; 1600 } 1601 assertThat(sessionIds, hasItemInArray(sessionId)); 1602 } 1603 assertSessionNotVisible(Integer[] sessionIds, int sessionId)1604 private void assertSessionNotVisible(Integer[] sessionIds, int sessionId) { 1605 if (!sGlobalFeatureEnabled) { 1606 return; 1607 } 1608 assertThat(sessionIds, not(hasItemInArray(sessionId))); 1609 } 1610 commitSession(int sessionId)1611 private static void commitSession(int sessionId) throws Exception { 1612 final PackageInstaller.Session session = 1613 InstallUtils.openPackageInstallerSession(sessionId); 1614 final LocalIntentSender sender = new LocalIntentSender(); 1615 session.commit(sender.getIntentSender()); 1616 InstallUtils.assertStatusSuccess(sender.getResult()); 1617 } 1618 adoptShellPermissions()1619 private void adoptShellPermissions() { 1620 InstrumentationRegistry 1621 .getInstrumentation() 1622 .getUiAutomation() 1623 .adoptShellPermissionIdentity(Manifest.permission.INSTALL_PACKAGES); 1624 } 1625 dropShellPermissions()1626 private void dropShellPermissions() { 1627 InstrumentationRegistry 1628 .getInstrumentation() 1629 .getUiAutomation() 1630 .dropShellPermissionIdentity(); 1631 } 1632 cleanUpSessions()1633 private void cleanUpSessions() { 1634 InstallUtils.getPackageInstaller().getMySessions().forEach(info -> { 1635 try { 1636 InstallUtils.getPackageInstaller().abandonSession(info.getSessionId()); 1637 } catch (Exception ignore) { 1638 } 1639 }); 1640 } 1641 1642 @Test queriesResolver_grantsVisibilityToProvider()1643 public void queriesResolver_grantsVisibilityToProvider() throws Exception { 1644 assertNotVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM); 1645 1646 String[] result = sendCommandBlocking( 1647 QUERIES_NOTHING_PERM, QUERIES_NOTHING_PROVIDER, null, ACTION_QUERY_RESOLVER) 1648 .getStringArray(Intent.EXTRA_RETURN_RESULT); 1649 Arrays.sort(result); 1650 assertThat(QUERIES_NOTHING_PERM + " not visible to " + QUERIES_NOTHING_PROVIDER 1651 + " during resolver interaction", 1652 Arrays.binarySearch(result, QUERIES_NOTHING_PERM), 1653 greaterThanOrEqualTo(0)); 1654 1655 assertVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM); 1656 } 1657 1658 @Test bindService_consistentVisibility()1659 public void bindService_consistentVisibility() throws Exception { 1660 // Ensure package visibility isn't impacted by optimization or cached result. 1661 // Target service shouldn't be visible to app without query permission even if 1662 // another app with query permission is binding it. 1663 assertServiceVisible(QUERIES_NOTHING_PERM, TARGET_FILTERS); 1664 assertServiceNotVisible(QUERIES_NOTHING, TARGET_FILTERS); 1665 } 1666 1667 @Test queriesPackage_getSyncAdapterTypes_canSeeSyncadapterTarget()1668 public void queriesPackage_getSyncAdapterTypes_canSeeSyncadapterTarget() throws Exception { 1669 assertVisible(QUERIES_PACKAGE, TARGET_SYNCADAPTER, this::getSyncAdapterTypes); 1670 } 1671 1672 @Test queriesNothing_getSyncAdapterTypes_cannotSeeSyncadapterTarget()1673 public void queriesNothing_getSyncAdapterTypes_cannotSeeSyncadapterTarget() throws Exception { 1674 assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER, this::getSyncAdapterTypes); 1675 assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER_SHARED_USER, 1676 this::getSyncAdapterTypes); 1677 } 1678 1679 @Test queriesNothingSharedUser_getSyncAdapterTypes_canSeeSyncadapterSharedUserTarget()1680 public void queriesNothingSharedUser_getSyncAdapterTypes_canSeeSyncadapterSharedUserTarget() 1681 throws Exception { 1682 assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SYNCADAPTER_SHARED_USER, 1683 this::getSyncAdapterTypes); 1684 } 1685 1686 @Test queriesPackage_getSyncAdapterPackages_canSeeSyncadapterTarget()1687 public void queriesPackage_getSyncAdapterPackages_canSeeSyncadapterTarget() 1688 throws Exception { 1689 assertVisible(QUERIES_PACKAGE, TARGET_SYNCADAPTER, 1690 this::getSyncAdapterPackagesForAuthorityAsUser); 1691 } 1692 1693 @Test queriesNothing_getSyncAdapterPackages_cannotSeeSyncadapterTarget()1694 public void queriesNothing_getSyncAdapterPackages_cannotSeeSyncadapterTarget() 1695 throws Exception { 1696 assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER, 1697 this::getSyncAdapterPackagesForAuthorityAsUser); 1698 assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER_SHARED_USER, 1699 this::getSyncAdapterPackagesForAuthorityAsUser); 1700 } 1701 1702 @Test queriesPackage_requestSync_canSeeSyncadapterTarget()1703 public void queriesPackage_requestSync_canSeeSyncadapterTarget() 1704 throws Exception { 1705 assertThat(requestSyncAndAwaitStatus(QUERIES_PACKAGE, 1706 ACCOUNT_SYNCADAPTER, TARGET_SYNCADAPTER), 1707 is(true)); 1708 } 1709 1710 @Test queriesNothingSharedUser_requestSync_canSeeSyncadapterSharedUserTarget()1711 public void queriesNothingSharedUser_requestSync_canSeeSyncadapterSharedUserTarget() 1712 throws Exception { 1713 assertThat(requestSyncAndAwaitStatus(QUERIES_NOTHING_SHARED_USER, 1714 ACCOUNT_SYNCADAPTER_SHARED_USER, TARGET_SYNCADAPTER_SHARED_USER), 1715 is(true)); 1716 } 1717 1718 @Test queriesNothing_requestSync_cannotSeeSyncadapterTarget()1719 public void queriesNothing_requestSync_cannotSeeSyncadapterTarget() { 1720 assertThrows(MissingCallbackException.class, 1721 () -> requestSyncAndAwaitStatus(QUERIES_NOTHING, 1722 ACCOUNT_SYNCADAPTER, TARGET_SYNCADAPTER)); 1723 assertThrows(MissingCallbackException.class, 1724 () -> requestSyncAndAwaitStatus(QUERIES_NOTHING, 1725 ACCOUNT_SYNCADAPTER_SHARED_USER, TARGET_SYNCADAPTER_SHARED_USER)); 1726 } 1727 1728 @Test queriesNothingSharedUser_getSyncAdapterPackages_canSeeSyncadapterSharedUserTarget()1729 public void queriesNothingSharedUser_getSyncAdapterPackages_canSeeSyncadapterSharedUserTarget() 1730 throws Exception { 1731 assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SYNCADAPTER_SHARED_USER, 1732 this::getSyncAdapterPackagesForAuthorityAsUser); 1733 } 1734 1735 @Test launcherAppsIsActivityEnabled_queriesActivityAction_canSeeActivity()1736 public void launcherAppsIsActivityEnabled_queriesActivityAction_canSeeActivity() 1737 throws Exception { 1738 final ComponentName targetFilters = ComponentName.createRelative(TARGET_FILTERS, 1739 ACTIVITY_CLASS_DUMMY_ACTIVITY); 1740 assertThat(QUERIES_ACTIVITY_ACTION + " should be able to see " + targetFilters, 1741 launcherAppsIsActivityEnabled(QUERIES_ACTIVITY_ACTION, targetFilters), 1742 is(true)); 1743 } 1744 1745 @Test launcherAppsIsActivityEnabled_queriesNothing_cannotSeeActivity()1746 public void launcherAppsIsActivityEnabled_queriesNothing_cannotSeeActivity() 1747 throws Exception { 1748 final ComponentName targetFilters = ComponentName.createRelative(TARGET_FILTERS, 1749 ACTIVITY_CLASS_DUMMY_ACTIVITY); 1750 assertThat(QUERIES_ACTIVITY_ACTION + " should not be able to see " + targetFilters, 1751 launcherAppsIsActivityEnabled(QUERIES_NOTHING, targetFilters), 1752 is(false)); 1753 } 1754 1755 @Test launcherAppsGetSuspendedPackageLauncherExtras_queriesNothingHasPerm_canGetExtras()1756 public void launcherAppsGetSuspendedPackageLauncherExtras_queriesNothingHasPerm_canGetExtras() 1757 throws Exception { 1758 try { 1759 setPackagesSuspendedWithLauncherExtras(/* suspend */ true, 1760 Arrays.asList(TARGET_NO_API), /* extras */ true); 1761 Assert.assertNotNull(launcherAppsGetSuspendedPackageLauncherExtras(QUERIES_NOTHING_PERM, 1762 TARGET_NO_API)); 1763 } finally { 1764 setPackagesSuspended(/* suspend */ false, Arrays.asList(TARGET_NO_API)); 1765 } 1766 } 1767 1768 @Test launcherAppsGetSuspendedPackageLauncherExtras_queriesNothing_cannotGetExtras()1769 public void launcherAppsGetSuspendedPackageLauncherExtras_queriesNothing_cannotGetExtras() 1770 throws Exception { 1771 try { 1772 setPackagesSuspendedWithLauncherExtras(/* suspend */ true, 1773 Arrays.asList(TARGET_NO_API), /* extras */ true); 1774 Assert.assertNull(launcherAppsGetSuspendedPackageLauncherExtras(QUERIES_NOTHING, 1775 TARGET_NO_API)); 1776 } finally { 1777 setPackagesSuspended(/* suspend */ false, Arrays.asList(TARGET_NO_API)); 1778 } 1779 } 1780 1781 @Test launcherAppsShouldHideFromSuggestions_queriesPackage_canSeeNoApi()1782 public void launcherAppsShouldHideFromSuggestions_queriesPackage_canSeeNoApi() 1783 throws Exception { 1784 setDistractingPackageRestrictions(new String[]{TARGET_NO_API}, 1785 PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS); 1786 1787 try { 1788 final boolean hideFromSuggestions = shouldHideFromSuggestions( 1789 QUERIES_PACKAGE, TARGET_NO_API); 1790 assertThat(hideFromSuggestions, is(true)); 1791 } finally { 1792 setDistractingPackageRestrictions(new String[]{TARGET_NO_API}, 1793 PackageManager.RESTRICTION_NONE); 1794 } 1795 } 1796 1797 @Test launcherAppsShouldHideFromSuggestions_queriesNothing_cannotSeeNoApi()1798 public void launcherAppsShouldHideFromSuggestions_queriesNothing_cannotSeeNoApi() 1799 throws Exception { 1800 setDistractingPackageRestrictions(new String[]{TARGET_NO_API}, 1801 PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS); 1802 1803 try { 1804 final boolean hideFromSuggestions = shouldHideFromSuggestions( 1805 QUERIES_NOTHING, TARGET_NO_API); 1806 assertThat(hideFromSuggestions, is(false)); 1807 } finally { 1808 setDistractingPackageRestrictions(new String[]{TARGET_NO_API}, 1809 PackageManager.RESTRICTION_NONE); 1810 } 1811 } 1812 1813 @Test queriesPackage_canSeeAppWidgetProviderTarget()1814 public void queriesPackage_canSeeAppWidgetProviderTarget() throws Exception { 1815 assumeTrue(InstrumentationRegistry.getInstrumentation().getContext().getPackageManager() 1816 .hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)); 1817 1818 assertVisible(QUERIES_PACKAGE, TARGET_APPWIDGETPROVIDER, 1819 this::getInstalledAppWidgetProviders); 1820 } 1821 1822 @Test queriesNothing_cannotSeeAppWidgetProviderTarget()1823 public void queriesNothing_cannotSeeAppWidgetProviderTarget() throws Exception { 1824 assumeTrue(InstrumentationRegistry.getInstrumentation().getContext().getPackageManager() 1825 .hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)); 1826 1827 assertNotVisible(QUERIES_NOTHING, TARGET_APPWIDGETPROVIDER, 1828 this::getInstalledAppWidgetProviders); 1829 assertNotVisible(QUERIES_NOTHING, TARGET_APPWIDGETPROVIDER_SHARED_USER, 1830 this::getInstalledAppWidgetProviders); 1831 } 1832 1833 @Test queriesNothingSharedUser_canSeeAppWidgetProviderSharedUserTarget()1834 public void queriesNothingSharedUser_canSeeAppWidgetProviderSharedUserTarget() 1835 throws Exception { 1836 assumeTrue(InstrumentationRegistry.getInstrumentation().getContext().getPackageManager() 1837 .hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)); 1838 1839 assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_APPWIDGETPROVIDER_SHARED_USER, 1840 this::getInstalledAppWidgetProviders); 1841 } 1842 1843 @Test queriesNothing_cannotSeeSharedLibraryDependentPackages()1844 public void queriesNothing_cannotSeeSharedLibraryDependentPackages() throws Exception { 1845 assertNotVisible(QUERIES_NOTHING, TARGET_NO_API, this::getSharedLibraryDependentPackages); 1846 assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS, this::getSharedLibraryDependentPackages); 1847 assertNotVisible(QUERIES_NOTHING, TARGET_SHARED_USER, 1848 this::getSharedLibraryDependentPackages); 1849 1850 } 1851 1852 @Test queriesPackage_canSeeSharedLibraryDependentPackages()1853 public void queriesPackage_canSeeSharedLibraryDependentPackages() throws Exception { 1854 assertVisible(QUERIES_PACKAGE, TARGET_NO_API, this::getSharedLibraryDependentPackages); 1855 assertVisible(QUERIES_PACKAGE, TARGET_SHARED_USER, this::getSharedLibraryDependentPackages); 1856 } 1857 1858 @Test queriesNothingSharedUser_canSeeSharedUserInSharedLibraryDependentPackages()1859 public void queriesNothingSharedUser_canSeeSharedUserInSharedLibraryDependentPackages() 1860 throws Exception { 1861 assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SHARED_USER, 1862 this::getSharedLibraryDependentPackages); 1863 } 1864 1865 @Test queriesNothing_cannotSeePreferredActivityTarget()1866 public void queriesNothing_cannotSeePreferredActivityTarget() throws Exception { 1867 addPreferredActivity(); 1868 try { 1869 assertNotVisible(QUERIES_NOTHING, TARGET_PREFERRED_ACTIVITY, 1870 this::getPreferredActivities); 1871 } finally { 1872 clearPreferredActivity(); 1873 } 1874 } 1875 1876 @Test queriesPackage_canSeePreferredActivityTarget()1877 public void queriesPackage_canSeePreferredActivityTarget() throws Exception { 1878 addPreferredActivity(); 1879 try { 1880 assertVisible(QUERIES_PACKAGE, TARGET_PREFERRED_ACTIVITY, 1881 this::getPreferredActivities); 1882 } finally { 1883 clearPreferredActivity(); 1884 } 1885 } 1886 1887 @Test queriesNothing_setInstallerPackageName_targetIsNoApi_throwsException()1888 public void queriesNothing_setInstallerPackageName_targetIsNoApi_throwsException() { 1889 final Exception ex = assertThrows(IllegalArgumentException.class, 1890 () -> setInstallerPackageName(QUERIES_NOTHING, TARGET_NO_API, QUERIES_NOTHING)); 1891 assertThat(ex.getMessage(), containsString(TARGET_NO_API)); 1892 } 1893 1894 @Test queriesNothing_setInstallerPackageName_installerIsNoApi_throwsException()1895 public void queriesNothing_setInstallerPackageName_installerIsNoApi_throwsException() { 1896 final Exception ex = assertThrows(IllegalArgumentException.class, 1897 () -> setInstallerPackageName(QUERIES_NOTHING, QUERIES_NOTHING, TARGET_NO_API)); 1898 assertThat(ex.getMessage(), containsString(TARGET_NO_API)); 1899 } 1900 1901 @Test queriesPackageHasProvider_checkUriPermission_canSeeNoApi()1902 public void queriesPackageHasProvider_checkUriPermission_canSeeNoApi() throws Exception { 1903 final int permissionResult = checkUriPermission(QUERIES_PACKAGE_PROVIDER, TARGET_NO_API); 1904 assertThat(permissionResult, is(PackageManager.PERMISSION_GRANTED)); 1905 } 1906 1907 @Test queriesPackageHasProvider_checkUriPermission_cannotSeeFilters()1908 public void queriesPackageHasProvider_checkUriPermission_cannotSeeFilters() throws Exception { 1909 final int permissionResult = checkUriPermission(QUERIES_PACKAGE_PROVIDER, TARGET_FILTERS); 1910 assertThat(permissionResult, is(PackageManager.PERMISSION_DENIED)); 1911 } 1912 1913 @Test queriesPackageHasProvider_grantUriPermission_canSeeNoApi()1914 public void queriesPackageHasProvider_grantUriPermission_canSeeNoApi() throws Exception { 1915 try { 1916 grantUriPermission(QUERIES_PACKAGE_PROVIDER, TARGET_NO_API); 1917 assertThat(InstrumentationRegistry.getInstrumentation().getContext() 1918 .checkUriPermission( 1919 Uri.parse("content://" + QUERIES_PACKAGE_PROVIDER), 1920 0 /* pid */, 1921 sPm.getPackageUid(TARGET_NO_API, 0 /* flags */), 1922 Intent.FLAG_GRANT_READ_URI_PERMISSION), 1923 is(PackageManager.PERMISSION_GRANTED)); 1924 } finally { 1925 revokeUriPermission(QUERIES_PACKAGE_PROVIDER); 1926 } 1927 } 1928 1929 @Test queriesPackageHasProvider_grantUriPermission_cannotSeeFilters()1930 public void queriesPackageHasProvider_grantUriPermission_cannotSeeFilters() throws Exception { 1931 try { 1932 grantUriPermission(QUERIES_PACKAGE_PROVIDER, TARGET_FILTERS); 1933 assertThat(InstrumentationRegistry.getInstrumentation().getContext() 1934 .checkUriPermission( 1935 Uri.parse("content://" + QUERIES_PACKAGE_PROVIDER), 1936 0 /* pid */, 1937 sPm.getPackageUid(TARGET_FILTERS, 0 /* flags */), 1938 Intent.FLAG_GRANT_READ_URI_PERMISSION), 1939 is(PackageManager.PERMISSION_DENIED)); 1940 } finally { 1941 revokeUriPermission(QUERIES_PACKAGE_PROVIDER); 1942 } 1943 } 1944 1945 @Test canPackageQuery_queriesActivityAction_canSeeFilters()1946 public void canPackageQuery_queriesActivityAction_canSeeFilters() throws Exception { 1947 assertThat(sPm.canPackageQuery(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS), 1948 is(true)); 1949 } 1950 1951 @Test canPackageQuery_queriesNothing_cannotSeeFilters()1952 public void canPackageQuery_queriesNothing_cannotSeeFilters() throws Exception { 1953 assertThat(sPm.canPackageQuery(QUERIES_NOTHING, TARGET_FILTERS), 1954 is(false)); 1955 } 1956 1957 @Test canPackageQuery_withNonexistentPackages()1958 public void canPackageQuery_withNonexistentPackages() { 1959 assertThrows(PackageManager.NameNotFoundException.class, 1960 () -> sPm.canPackageQuery( 1961 TEST_NONEXISTENT_PACKAGE_NAME_1, TEST_NONEXISTENT_PACKAGE_NAME_2)); 1962 assertThrows(PackageManager.NameNotFoundException.class, 1963 () -> sPm.canPackageQuery( 1964 QUERIES_NOTHING_PERM, TEST_NONEXISTENT_PACKAGE_NAME_2)); 1965 assertThrows(PackageManager.NameNotFoundException.class, 1966 () -> sPm.canPackageQuery( 1967 TEST_NONEXISTENT_PACKAGE_NAME_1, TARGET_FILTERS)); 1968 } 1969 1970 @Test canPackageQuery_callerHasNoPackageVisibility()1971 public void canPackageQuery_callerHasNoPackageVisibility() { 1972 assertThrows(PackageManager.NameNotFoundException.class, 1973 () -> canPackageQuery( 1974 QUERIES_NOTHING, QUERIES_ACTIVITY_ACTION, TARGET_FILTERS)); 1975 assertThrows(PackageManager.NameNotFoundException.class, 1976 () -> canPackageQuery( 1977 QUERIES_NOTHING_SHARED_USER, QUERIES_PACKAGE, TARGET_SHARED_USER)); 1978 } 1979 1980 @Test canPackageQuery_cannotDetectPackageExistence()1981 public void canPackageQuery_cannotDetectPackageExistence() { 1982 ensurePackageIsNotInstalled(TARGET_STUB); 1983 final Exception ex1 = assertThrows(PackageManager.NameNotFoundException.class, 1984 () -> canPackageQuery(QUERIES_NOTHING, TARGET_STUB, "")); 1985 final StringWriter stackTrace1 = new StringWriter(); 1986 ex1.printStackTrace(new PrintWriter(stackTrace1)); 1987 1988 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 1989 1990 final Exception ex2 = assertThrows(PackageManager.NameNotFoundException.class, 1991 () -> canPackageQuery(QUERIES_NOTHING, TARGET_STUB, "")); 1992 final StringWriter stackTrace2 = new StringWriter(); 1993 ex1.printStackTrace(new PrintWriter(stackTrace2)); 1994 1995 assertThat(ex1.getMessage(), is(ex2.getMessage())); 1996 assertThat(stackTrace1.toString(), is(stackTrace2.toString())); 1997 } 1998 1999 @Test checkPackage_queriesNothing_validateFailed()2000 public void checkPackage_queriesNothing_validateFailed() { 2001 // Using ROOT_UID here to pass the check in #verifyAndGetBypass, this is intended by design. 2002 assertThrows(SecurityException.class, 2003 () -> checkPackage(QUERIES_NOTHING, TARGET_FILTERS, ROOT_UID)); 2004 } 2005 2006 @Test checkPackage_queriesNothing_targetIsNotExisting_validateFailed()2007 public void checkPackage_queriesNothing_targetIsNotExisting_validateFailed() { 2008 // Using ROOT_UID here to pass the check in #verifyAndGetBypass, this is intended by design. 2009 assertThrows(SecurityException.class, 2010 () -> checkPackage(QUERIES_NOTHING, TEST_NONEXISTENT_PACKAGE_NAME_1, ROOT_UID)); 2011 } 2012 2013 @Test checkPackage_queriesNothingHasPerm_validateSuccessful()2014 public void checkPackage_queriesNothingHasPerm_validateSuccessful() throws Exception { 2015 // Using ROOT_UID here to pass the check in #verifyAndGetBypass, this is intended by design. 2016 assertThat(checkPackage(QUERIES_NOTHING_PERM, TARGET_FILTERS, ROOT_UID), is(true)); 2017 } 2018 2019 @Test checkPackage_queriesNothingHasPerm_targetIsNotExisting_validateFailed()2020 public void checkPackage_queriesNothingHasPerm_targetIsNotExisting_validateFailed() 2021 throws Exception { 2022 // Using ROOT_UID here to pass the check in #verifyAndGetBypass, this is intended by design. 2023 assertThrows(SecurityException.class, 2024 () -> checkPackage(QUERIES_NOTHING_PERM, TEST_NONEXISTENT_PACKAGE_NAME_1, 2025 ROOT_UID)); 2026 } 2027 2028 @Test pendingIntent_getCreatorPackage_queriesPackage_canSeeNoApi()2029 public void pendingIntent_getCreatorPackage_queriesPackage_canSeeNoApi() 2030 throws Exception { 2031 final PendingIntent pendingIntent = getPendingIntentActivity(TARGET_NO_API); 2032 assertThat(getPendingIntentCreatorPackage(QUERIES_PACKAGE, pendingIntent), 2033 is(TARGET_NO_API)); 2034 } 2035 2036 @Test pendingIntent_getCreatorPackage_queriesNothing_cannotSeeNoApi()2037 public void pendingIntent_getCreatorPackage_queriesNothing_cannotSeeNoApi() 2038 throws Exception { 2039 final PendingIntent pendingIntent = getPendingIntentActivity(TARGET_NO_API); 2040 assertThat(getPendingIntentCreatorPackage(QUERIES_NOTHING, pendingIntent), 2041 is(emptyOrNullString())); 2042 } 2043 2044 @Test makeUidVisible_throwsException()2045 public void makeUidVisible_throwsException() throws Exception { 2046 final int recipientUid = sPm.getPackageUid( 2047 QUERIES_NOTHING, PackageManager.PackageInfoFlags.of(0)); 2048 final int visibleUid = sPm.getPackageUid( 2049 TARGET_NO_API, PackageManager.PackageInfoFlags.of(0)); 2050 assertThrows(SecurityException.class, 2051 () -> sPm.makeUidVisible(recipientUid, visibleUid)); 2052 } 2053 2054 @Test makeUidVisible_queriesNothing_canSeeStub()2055 public void makeUidVisible_queriesNothing_canSeeStub() throws Exception { 2056 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 2057 try { 2058 assertNotVisible(QUERIES_NOTHING, TARGET_STUB); 2059 2060 final int recipientUid = sPm.getPackageUid( 2061 QUERIES_NOTHING, PackageManager.PackageInfoFlags.of(0)); 2062 final int visibleUid = sPm.getPackageUid( 2063 TARGET_STUB, PackageManager.PackageInfoFlags.of(0)); 2064 SystemUtil.runWithShellPermissionIdentity( 2065 () -> sPm.makeUidVisible(recipientUid, visibleUid), 2066 Manifest.permission.MAKE_UID_VISIBLE); 2067 2068 assertVisible(QUERIES_NOTHING, TARGET_STUB); 2069 } finally { 2070 ensurePackageIsNotInstalled(TARGET_STUB); 2071 } 2072 } 2073 assertNotVisible(String sourcePackageName, String targetPackageName)2074 private void assertNotVisible(String sourcePackageName, String targetPackageName) 2075 throws Exception { 2076 if (!sGlobalFeatureEnabled) return; 2077 try { 2078 getPackageInfo(sourcePackageName, targetPackageName); 2079 fail(sourcePackageName + " should not be able to see " + targetPackageName); 2080 } catch (PackageManager.NameNotFoundException ignored) { 2081 } 2082 } 2083 assertServiceVisible(String sourcePackageName, String targetPackageName)2084 private void assertServiceVisible(String sourcePackageName, String targetPackageName) 2085 throws Exception { 2086 if (!sGlobalFeatureEnabled) return; 2087 assertTrue(bindService(sourcePackageName, targetPackageName)); 2088 } 2089 assertServiceNotVisible(String sourcePackageName, String targetPackageName)2090 private void assertServiceNotVisible(String sourcePackageName, String targetPackageName) 2091 throws Exception { 2092 if (!sGlobalFeatureEnabled) return; 2093 assertFalse(bindService(sourcePackageName, targetPackageName)); 2094 } 2095 2096 interface ThrowingBiFunction<T, U, R> { apply(T arg1, U arg2)2097 R apply(T arg1, U arg2) throws Exception; 2098 } 2099 2100 interface ThrowingFunction<T, R> { apply(T arg1)2101 R apply(T arg1) throws Exception; 2102 } 2103 assertNotQueryable(String sourcePackageName, String targetPackageName, String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)2104 private void assertNotQueryable(String sourcePackageName, String targetPackageName, 2105 String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod) 2106 throws Exception { 2107 if (!sGlobalFeatureEnabled) return; 2108 Intent intent = new Intent(intentAction); 2109 String[] queryablePackageNames = commandMethod.apply(sourcePackageName, intent); 2110 for (String packageName : queryablePackageNames) { 2111 if (packageName.contentEquals(targetPackageName)) { 2112 fail(sourcePackageName + " should not be able to query " + targetPackageName + 2113 " via " + intentAction); 2114 } 2115 } 2116 } 2117 assertQueryable(String sourcePackageName, String targetPackageName, String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)2118 private void assertQueryable(String sourcePackageName, String targetPackageName, 2119 String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod) 2120 throws Exception { 2121 if (!sGlobalFeatureEnabled) return; 2122 Intent intent = new Intent(intentAction); 2123 String[] queryablePackageNames = commandMethod.apply(sourcePackageName, intent); 2124 for (String packageName : queryablePackageNames) { 2125 if (packageName.contentEquals(targetPackageName)) { 2126 return; 2127 } 2128 } 2129 fail(sourcePackageName + " should be able to query " + targetPackageName + " via " 2130 + intentAction); 2131 } 2132 assertVisible(String sourcePackageName, String targetPackageName, ThrowingFunction<String, String[]> commandMethod)2133 private void assertVisible(String sourcePackageName, String targetPackageName, 2134 ThrowingFunction<String, String[]> commandMethod) throws Exception { 2135 if (!sGlobalFeatureEnabled) return; 2136 final String[] packageNames = commandMethod.apply(sourcePackageName); 2137 assertThat("The list of package names should not be null", 2138 packageNames, notNullValue()); 2139 assertThat(sourcePackageName + " should be able to see " + targetPackageName, 2140 packageNames, hasItemInArray(targetPackageName)); 2141 } 2142 assertNotVisible(String sourcePackageName, String targetPackageName, ThrowingFunction<String, String[]> commandMethod)2143 private void assertNotVisible(String sourcePackageName, String targetPackageName, 2144 ThrowingFunction<String, String[]> commandMethod) throws Exception { 2145 if (!sGlobalFeatureEnabled) return; 2146 final String[] packageNames = commandMethod.apply(sourcePackageName); 2147 assertThat("The list of package names should not be null", 2148 packageNames, notNullValue()); 2149 assertThat(sourcePackageName + " should not be able to see " + targetPackageName, 2150 packageNames, not(hasItemInArray(targetPackageName))); 2151 } 2152 assertVisible(String sourcePackageName, String targetPackageName, ThrowingBiFunction<String, String, String[]> commandMethod)2153 private void assertVisible(String sourcePackageName, String targetPackageName, 2154 ThrowingBiFunction<String, String, String[]> commandMethod) throws Exception { 2155 if (!sGlobalFeatureEnabled) return; 2156 final String[] packageNames = commandMethod.apply(sourcePackageName, targetPackageName); 2157 assertThat(sourcePackageName + " should be able to see " + targetPackageName, 2158 packageNames, hasItemInArray(targetPackageName)); 2159 } 2160 assertNotVisible(String sourcePackageName, String targetPackageName, ThrowingBiFunction<String, String, String[]> commandMethod)2161 private void assertNotVisible(String sourcePackageName, String targetPackageName, 2162 ThrowingBiFunction<String, String, String[]> commandMethod) throws Exception { 2163 if (!sGlobalFeatureEnabled) return; 2164 final String[] packageNames = commandMethod.apply(sourcePackageName, targetPackageName); 2165 assertThat(sourcePackageName + " should not be able to see " + targetPackageName, 2166 packageNames, not(hasItemInArray(targetPackageName))); 2167 } 2168 assertBroadcastSuspendedVisible(String sourcePackageName, List<String> expectedVisiblePackages, List<String> packagesToSuspend)2169 private void assertBroadcastSuspendedVisible(String sourcePackageName, 2170 List<String> expectedVisiblePackages, List<String> packagesToSuspend) 2171 throws Exception { 2172 final Bundle extras = new Bundle(); 2173 extras.putStringArray(EXTRA_PACKAGES, packagesToSuspend.toArray(new String[] {})); 2174 final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null, 2175 /* targetUid */ INVALID_UID, extras, Constants.ACTION_AWAIT_PACKAGES_SUSPENDED, 2176 /* waitForReady */ true); 2177 try { 2178 setPackagesSuspended(true, packagesToSuspend); 2179 final String[] suspendedPackages = result.await().getStringArray(EXTRA_PACKAGES); 2180 assertThat(suspendedPackages, arrayContainingInAnyOrder( 2181 expectedVisiblePackages.toArray())); 2182 } finally { 2183 setPackagesSuspended(false, packagesToSuspend); 2184 } 2185 } 2186 getInstalledAccessibilityServices(String sourcePackageName)2187 private String[] getInstalledAccessibilityServices (String sourcePackageName) 2188 throws Exception { 2189 final Bundle response = sendCommandBlocking(sourcePackageName, null /*targetPackageName*/, 2190 null /*queryIntent*/, ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES); 2191 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2192 } 2193 getPackageInfo(String sourcePackageName, String targetPackageName)2194 private PackageInfo getPackageInfo(String sourcePackageName, String targetPackageName) 2195 throws Exception { 2196 Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, 2197 null /*queryIntent*/, ACTION_GET_PACKAGE_INFO); 2198 return response.getParcelable(Intent.EXTRA_RETURN_RESULT); 2199 } 2200 getPackagesForUid(String sourcePackageName, int targetUid)2201 private String[] getPackagesForUid(String sourcePackageName, int targetUid) 2202 throws Exception { 2203 final Bundle response = sendCommandBlocking(sourcePackageName, targetUid, 2204 /* intentExtra */ null, ACTION_GET_PACKAGES_FOR_UID); 2205 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2206 } 2207 getNameForUid(String sourcePackageName, int targetUid)2208 private String getNameForUid(String sourcePackageName, int targetUid) throws Exception { 2209 final Bundle response = sendCommandBlocking(sourcePackageName, targetUid, 2210 /* intentExtra */ null, ACTION_GET_NAME_FOR_UID); 2211 return response.getString(Intent.EXTRA_RETURN_RESULT); 2212 } 2213 getNamesForUids(String sourcePackageName, int targetUid)2214 private String[] getNamesForUids(String sourcePackageName, int targetUid) throws Exception { 2215 final Bundle response = sendCommandBlocking(sourcePackageName, targetUid, 2216 /* intentExtra */ null, ACTION_GET_NAMES_FOR_UIDS); 2217 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2218 } 2219 checkSignatures(String sourcePackageName, int targetUid)2220 private int checkSignatures(String sourcePackageName, int targetUid) throws Exception { 2221 final Bundle response = sendCommandBlocking(sourcePackageName, targetUid, 2222 /* intentExtra */ null, ACTION_CHECK_SIGNATURES); 2223 return response.getInt(Intent.EXTRA_RETURN_RESULT); 2224 } 2225 hasSigningCertificate(String sourcePackageName, int targetUid, byte[] cert)2226 private boolean hasSigningCertificate(String sourcePackageName, int targetUid, byte[] cert) 2227 throws Exception { 2228 final Bundle extra = new Bundle(); 2229 extra.putByteArray(EXTRA_CERT, cert); 2230 final Bundle response = sendCommandBlocking(sourcePackageName, targetUid, extra, 2231 ACTION_HAS_SIGNING_CERTIFICATE); 2232 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2233 } 2234 convertSignaturesToCertificates(Signature[] signatures)2235 private List<Certificate> convertSignaturesToCertificates(Signature[] signatures) 2236 throws Exception { 2237 final CertificateFactory cf = CertificateFactory.getInstance("X.509"); 2238 ArrayList<Certificate> certs = new ArrayList<>(signatures.length); 2239 for (Signature signature : signatures) { 2240 final InputStream is = new ByteArrayInputStream(signature.toByteArray()); 2241 final X509Certificate cert = (X509Certificate) cf.generateCertificate(is); 2242 certs.add(cert); 2243 } 2244 return certs; 2245 } 2246 checkPackage(String sourcePackageName, String targetPackageName, int targetUid)2247 private boolean checkPackage(String sourcePackageName, String targetPackageName, int targetUid) 2248 throws Exception { 2249 final Bundle extra = new Bundle(); 2250 extra.putInt(EXTRA_UID, targetUid); 2251 final Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, extra, 2252 ACTION_CHECK_PACKAGE); 2253 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2254 } 2255 startForResult(String sourcePackageName, String targetPackageName)2256 private PackageInfo startForResult(String sourcePackageName, String targetPackageName) 2257 throws Exception { 2258 Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, 2259 null /*queryIntent*/, ACTION_START_FOR_RESULT); 2260 return response.getParcelable(Intent.EXTRA_RETURN_RESULT); 2261 } 2262 startSenderForResult(String sourcePackageName, String targetPackageName)2263 private PackageInfo startSenderForResult(String sourcePackageName, String targetPackageName) 2264 throws Exception { 2265 PendingIntent pendingIntent = PendingIntent.getActivity( 2266 InstrumentationRegistry.getInstrumentation().getContext(), 100, 2267 new Intent("android.appenumeration.cts.action.SEND_RESULT").setComponent( 2268 new ComponentName(targetPackageName, 2269 "android.appenumeration.cts.TestActivity")), 2270 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); 2271 2272 Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, 2273 pendingIntent /*queryIntent*/, Constants.ACTION_START_SENDER_FOR_RESULT); 2274 return response.getParcelable(Intent.EXTRA_RETURN_RESULT); 2275 } 2276 2277 queryIntentActivities(String sourcePackageName, Intent queryIntent)2278 private String[] queryIntentActivities(String sourcePackageName, Intent queryIntent) 2279 throws Exception { 2280 Bundle response = 2281 sendCommandBlocking(sourcePackageName, null, queryIntent, ACTION_QUERY_ACTIVITIES); 2282 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2283 } 2284 queryIntentServices(String sourcePackageName, Intent queryIntent)2285 private String[] queryIntentServices(String sourcePackageName, Intent queryIntent) 2286 throws Exception { 2287 Bundle response = sendCommandBlocking(sourcePackageName, null, queryIntent, 2288 ACTION_QUERY_SERVICES); 2289 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2290 } 2291 queryIntentProviders(String sourcePackageName, Intent queryIntent)2292 private String[] queryIntentProviders(String sourcePackageName, Intent queryIntent) 2293 throws Exception { 2294 Bundle response = sendCommandBlocking(sourcePackageName, null, queryIntent, 2295 ACTION_QUERY_PROVIDERS); 2296 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2297 } 2298 getInstalledPackages(String sourcePackageNames, int flags)2299 private String[] getInstalledPackages(String sourcePackageNames, int flags) throws Exception { 2300 Bundle response = sendCommandBlocking(sourcePackageNames, null, 2301 new Intent().putExtra(EXTRA_FLAGS, flags), ACTION_GET_INSTALLED_PACKAGES); 2302 return response.getStringArray(Intent.EXTRA_RETURN_RESULT); 2303 } 2304 startExplicitIntentViaComponent(String sourcePackage, String targetPackage)2305 private void startExplicitIntentViaComponent(String sourcePackage, String targetPackage) 2306 throws Exception { 2307 sendCommandBlocking(sourcePackage, targetPackage, 2308 new Intent().setComponent(new ComponentName(targetPackage, 2309 ACTIVITY_CLASS_DUMMY_ACTIVITY)), 2310 ACTION_START_DIRECTLY); 2311 } startExplicitIntentViaPackageName(String sourcePackage, String targetPackage)2312 private void startExplicitIntentViaPackageName(String sourcePackage, String targetPackage) 2313 throws Exception { 2314 sendCommandBlocking(sourcePackage, targetPackage, 2315 new Intent().setPackage(targetPackage), 2316 ACTION_START_DIRECTLY); 2317 } 2318 startImplicitIntent(String sourcePackage)2319 private void startImplicitIntent(String sourcePackage) throws Exception { 2320 sendCommandBlocking(sourcePackage, TARGET_FILTERS, new Intent(ACTION_MANIFEST_ACTIVITY), 2321 ACTION_START_DIRECTLY); 2322 } 2323 bindService(String sourcePackageName, String targetPackageName)2324 private boolean bindService(String sourcePackageName, String targetPackageName) 2325 throws Exception { 2326 final Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, 2327 /* intentExtra */ null, ACTION_BIND_SERVICE); 2328 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2329 } 2330 getSyncAdapterTypes(String sourcePackageName)2331 private String[] getSyncAdapterTypes(String sourcePackageName) throws Exception { 2332 final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null, 2333 /* intentExtra */ null, ACTION_GET_SYNCADAPTER_TYPES); 2334 final List<Parcelable> parcelables = response.getParcelableArrayList( 2335 Intent.EXTRA_RETURN_RESULT); 2336 return parcelables.stream() 2337 .map(parcelable -> ((SyncAdapterType) parcelable).getPackageName()) 2338 .distinct() 2339 .toArray(String[]::new); 2340 } 2341 getInstalledAppWidgetProviders(String sourcePackageName)2342 private String[] getInstalledAppWidgetProviders(String sourcePackageName) throws Exception { 2343 final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null, 2344 /* intentExtra */ null, ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS); 2345 final List<Parcelable> parcelables = response.getParcelableArrayList( 2346 Intent.EXTRA_RETURN_RESULT); 2347 return parcelables.stream() 2348 .map(parcelable -> ((AppWidgetProviderInfo) parcelable).provider.getPackageName()) 2349 .distinct() 2350 .toArray(String[]::new); 2351 } 2352 getSyncAdapterPackagesForAuthorityAsUser(String sourcePackageName, String targetPackageName)2353 private String[] getSyncAdapterPackagesForAuthorityAsUser(String sourcePackageName, 2354 String targetPackageName) throws Exception { 2355 final Bundle extraData = new Bundle(); 2356 extraData.putString(EXTRA_AUTHORITY, targetPackageName + ".authority"); 2357 extraData.putInt(Intent.EXTRA_USER, Process.myUserHandle().getIdentifier()); 2358 final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null, 2359 extraData, ACTION_GET_SYNCADAPTER_PACKAGES_FOR_AUTHORITY); 2360 return response.getStringArray(Intent.EXTRA_PACKAGES); 2361 } 2362 requestSyncAndAwaitStatus(String sourcePackageName, Account account, String targetPackageName)2363 private boolean requestSyncAndAwaitStatus(String sourcePackageName, Account account, 2364 String targetPackageName) throws Exception { 2365 final Bundle extraData = new Bundle(); 2366 extraData.putParcelable(EXTRA_ACCOUNT, account); 2367 extraData.putString(EXTRA_AUTHORITY, targetPackageName + ".authority"); 2368 final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null, 2369 extraData, ACTION_REQUEST_SYNC_AND_AWAIT_STATUS); 2370 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2371 } 2372 setPackagesSuspended(boolean suspend, List<String> packages)2373 private void setPackagesSuspended(boolean suspend, List<String> packages) { 2374 setPackagesSuspendedWithLauncherExtras(suspend, packages, /* persistableBundle */ false); 2375 } 2376 setPackagesSuspendedWithLauncherExtras(boolean suspend, List<String> packages, boolean extras)2377 private void setPackagesSuspendedWithLauncherExtras(boolean suspend, List<String> packages, 2378 boolean extras) { 2379 final StringBuilder cmd = new StringBuilder("pm "); 2380 if (suspend) { 2381 cmd.append("suspend"); 2382 } else { 2383 cmd.append("unsuspend"); 2384 } 2385 cmd.append(" --user cur"); 2386 if (extras) { 2387 cmd.append(" --les foo bar"); 2388 } 2389 packages.stream().forEach(p -> cmd.append(" ").append(p)); 2390 runShellCommand(cmd.toString()); 2391 } 2392 launcherAppsIsActivityEnabled(String sourcePackageName, ComponentName componentName)2393 private boolean launcherAppsIsActivityEnabled(String sourcePackageName, 2394 ComponentName componentName) throws Exception { 2395 final Bundle extraData = new Bundle(); 2396 extraData.putString(Intent.EXTRA_COMPONENT_NAME, componentName.flattenToString()); 2397 final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null, 2398 extraData, ACTION_LAUNCHER_APPS_IS_ACTIVITY_ENABLED); 2399 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2400 } 2401 launcherAppsGetSuspendedPackageLauncherExtras(String sourcePackageName, String targetPackageName)2402 private Bundle launcherAppsGetSuspendedPackageLauncherExtras(String sourcePackageName, 2403 String targetPackageName) throws Exception { 2404 final Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, 2405 /* extraData */ null, ACTION_LAUNCHER_APPS_GET_SUSPENDED_PACKAGE_LAUNCHER_EXTRAS); 2406 return response.getBundle(Intent.EXTRA_RETURN_RESULT); 2407 } 2408 getSharedLibraryDependentPackages(String sourcePackageName)2409 private String[] getSharedLibraryDependentPackages(String sourcePackageName) throws Exception { 2410 final Bundle extraData = new Bundle(); 2411 final Bundle response = sendCommandBlocking(sourcePackageName, TEST_SHARED_LIB_NAME, 2412 extraData, ACTION_GET_SHAREDLIBRARY_DEPENDENT_PACKAGES); 2413 return response.getStringArray(Intent.EXTRA_PACKAGES); 2414 } 2415 getPreferredActivities(String sourcePackageName)2416 private String[] getPreferredActivities(String sourcePackageName) throws Exception { 2417 final Bundle extraData = new Bundle(); 2418 final Bundle response = sendCommandBlocking(sourcePackageName, null /* targetPackageName */, 2419 extraData, ACTION_GET_PREFERRED_ACTIVITIES); 2420 return response.getStringArray(Intent.EXTRA_PACKAGES); 2421 } 2422 setInstallerPackageName(String sourcePackageName, String targetPackageName, String installerPackageName)2423 private void setInstallerPackageName(String sourcePackageName, String targetPackageName, 2424 String installerPackageName) throws Exception { 2425 final Bundle extraData = new Bundle(); 2426 extraData.putString(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName); 2427 sendCommandBlocking(sourcePackageName, targetPackageName, 2428 extraData, ACTION_SET_INSTALLER_PACKAGE_NAME); 2429 } 2430 setDistractingPackageRestrictions(String[] packagesToRestrict, int distractionFlags)2431 private void setDistractingPackageRestrictions(String[] packagesToRestrict, 2432 int distractionFlags) throws Exception { 2433 final String[] failed = SystemUtil.callWithShellPermissionIdentity( 2434 () -> sPm.setDistractingPackageRestrictions(packagesToRestrict, distractionFlags)); 2435 assertThat(failed, emptyArray()); 2436 } 2437 shouldHideFromSuggestions(String sourcePackageName, String targetPackageName)2438 private boolean shouldHideFromSuggestions(String sourcePackageName, String targetPackageName) 2439 throws Exception { 2440 final Bundle extraData = new Bundle(); 2441 extraData.putInt(Intent.EXTRA_USER, Process.myUserHandle().getIdentifier()); 2442 final Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, extraData, 2443 ACTION_LAUNCHER_APPS_SHOULD_HIDE_FROM_SUGGESTIONS); 2444 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2445 } 2446 checkUriPermission(String sourcePackageName, String targetPackageName)2447 private int checkUriPermission(String sourcePackageName, String targetPackageName) 2448 throws Exception { 2449 final int targetUid = sPm.getPackageUid(targetPackageName, /* flags */ 0); 2450 final Bundle extraData = new Bundle(); 2451 extraData.putString(EXTRA_AUTHORITY, sourcePackageName); 2452 final Result result = sendCommand(sourcePackageName, targetPackageName, targetUid, 2453 extraData, ACTION_CHECK_URI_PERMISSION, /* waitForReady */ false); 2454 final Bundle response = result.await(); 2455 return response.getInt(Intent.EXTRA_RETURN_RESULT); 2456 } 2457 grantUriPermission(String providerPackageName, String targetPackageName)2458 private void grantUriPermission(String providerPackageName, String targetPackageName) 2459 throws Exception { 2460 final Bundle extraData = new Bundle(); 2461 extraData.putString(EXTRA_AUTHORITY, providerPackageName); 2462 sendCommandBlocking(providerPackageName, targetPackageName, extraData, 2463 ACTION_GRANT_URI_PERMISSION); 2464 } 2465 revokeUriPermission(String providerPackageName)2466 private void revokeUriPermission(String providerPackageName) throws Exception { 2467 final Bundle extraData = new Bundle(); 2468 extraData.putString(EXTRA_AUTHORITY, providerPackageName); 2469 sendCommandBlocking(providerPackageName, null /* targetPackageName */, extraData, 2470 ACTION_REVOKE_URI_PERMISSION); 2471 } 2472 canPackageQuery(String callerPackageName, String sourcePackageName, String targetPackageName)2473 private boolean canPackageQuery(String callerPackageName, String sourcePackageName, 2474 String targetPackageName) throws Exception { 2475 final Bundle extraData = new Bundle(); 2476 extraData.putString(Intent.EXTRA_PACKAGE_NAME, targetPackageName); 2477 final Bundle response = sendCommandBlocking(callerPackageName, sourcePackageName, 2478 extraData, ACTION_CAN_PACKAGE_QUERY); 2479 return response.getBoolean(Intent.EXTRA_RETURN_RESULT); 2480 } 2481 getPendingIntentActivity(String sourcePackageName)2482 private PendingIntent getPendingIntentActivity(String sourcePackageName) throws Exception { 2483 final Bundle bundle = sendCommandBlocking(sourcePackageName, null /* targetPackageName */, 2484 null /* intentExtra */, ACTION_PENDING_INTENT_GET_ACTIVITY); 2485 return bundle.getParcelable(EXTRA_PENDING_INTENT); 2486 } 2487 getPendingIntentCreatorPackage(String sourcePackageName, PendingIntent pendingIntent)2488 private String getPendingIntentCreatorPackage(String sourcePackageName, 2489 PendingIntent pendingIntent) throws Exception { 2490 final Bundle bundle = sendCommandBlocking(sourcePackageName, null /* targetPackageName */, 2491 pendingIntent, ACTION_PENDING_INTENT_GET_CREATOR_PACKAGE); 2492 return bundle.getString(Intent.EXTRA_PACKAGE_NAME); 2493 } 2494 2495 interface Result { await()2496 Bundle await() throws Exception; 2497 } 2498 sendCommand(String sourcePackageName, @Nullable String targetPackageName, int targetUid, @Nullable Parcelable intentExtra, String action, boolean waitForReady)2499 private Result sendCommand(String sourcePackageName, @Nullable String targetPackageName, 2500 int targetUid, @Nullable Parcelable intentExtra, String action, boolean waitForReady) 2501 throws Exception { 2502 final Intent intent = new Intent(action) 2503 .setComponent(new ComponentName(sourcePackageName, ACTIVITY_CLASS_TEST)) 2504 // data uri unique to each activity start to ensure actual launch and not just 2505 // redisplay 2506 .setData(Uri.parse("test://" + UUID.randomUUID().toString())) 2507 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); 2508 if (targetPackageName != null) { 2509 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName); 2510 } 2511 if (targetUid > INVALID_UID) { 2512 intent.putExtra(Intent.EXTRA_UID, targetUid); 2513 } 2514 if (intentExtra != null) { 2515 if (intentExtra instanceof Intent) { 2516 intent.putExtra(Intent.EXTRA_INTENT, intentExtra); 2517 } else if (intentExtra instanceof PendingIntent) { 2518 intent.putExtra(EXTRA_PENDING_INTENT, intentExtra); 2519 } else if (intentExtra instanceof Bundle) { 2520 intent.putExtra(EXTRA_DATA, intentExtra); 2521 } 2522 } 2523 2524 final ConditionVariable latch = new ConditionVariable(); 2525 final AtomicReference<Bundle> resultReference = new AtomicReference<>(); 2526 final RemoteCallback callback = new RemoteCallback( 2527 bundle -> { 2528 resultReference.set(bundle); 2529 latch.open(); 2530 }, 2531 sResponseHandler); 2532 intent.putExtra(EXTRA_REMOTE_CALLBACK, callback); 2533 if (waitForReady) { 2534 AmUtils.waitForBroadcastIdle(); 2535 startAndWaitForCommandReady(intent); 2536 } else { 2537 final ActivityOptions options = ActivityOptions.makeBasic(); 2538 options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); 2539 InstrumentationRegistry.getInstrumentation().getContext().startActivity( 2540 intent, options.toBundle()); 2541 } 2542 return () -> { 2543 if (!latch.block(TimeUnit.SECONDS.toMillis(10))) { 2544 throw new TimeoutException( 2545 "Latch timed out while awiating a response from " + sourcePackageName); 2546 } 2547 final Bundle bundle = resultReference.get(); 2548 if (bundle != null && bundle.containsKey(EXTRA_ERROR)) { 2549 throw (Exception) Objects.requireNonNull(bundle.getSerializable(EXTRA_ERROR)); 2550 } 2551 return bundle; 2552 }; 2553 } 2554 2555 private void startAndWaitForCommandReady(Intent intent) throws Exception { 2556 final ConditionVariable latchForReady = new ConditionVariable(); 2557 final RemoteCallback readyCallback = new RemoteCallback(bundle -> latchForReady.open(), 2558 sResponseHandler); 2559 intent.putExtra(EXTRA_REMOTE_READY_CALLBACK, readyCallback); 2560 InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent); 2561 if (!latchForReady.block(TimeUnit.SECONDS.toMillis(10))) { 2562 throw new TimeoutException( 2563 "Latch timed out while awiating a response from command " + intent.getAction()); 2564 } 2565 } 2566 2567 private Bundle sendCommandBlocking(String sourcePackageName, @Nullable String targetPackageName, 2568 @Nullable Parcelable intentExtra, String action) 2569 throws Exception { 2570 final Result result = sendCommand(sourcePackageName, targetPackageName, 2571 /* targetUid */ INVALID_UID, intentExtra, action, /* waitForReady */ false); 2572 return result.await(); 2573 } 2574 2575 private Bundle sendCommandBlocking(String sourcePackageName, int targetUid, 2576 @Nullable Parcelable intentExtra, String action) 2577 throws Exception { 2578 final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null, 2579 targetUid, intentExtra, action, /* waitForReady */ false); 2580 return result.await(); 2581 } 2582 2583 private Result sendCommandAndWaitForLauncherAppsCallback(String sourcePackageName, 2584 int expectedEventCode) throws Exception { 2585 final Bundle extra = new Bundle(); 2586 extra.putInt(EXTRA_FLAGS, expectedEventCode); 2587 final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null, 2588 /* targetUid */ INVALID_UID, extra, ACTION_AWAIT_LAUNCHER_APPS_CALLBACK, 2589 /* waitForReady */ true); 2590 return result; 2591 } 2592 2593 private void ensurePackageIsInstalled(String packageName, String apkPath) { 2594 runShellCommand("pm install -R " + apkPath); 2595 PackageInfo info = null; 2596 try { 2597 info = sPm.getPackageInfo(packageName, /* flags */ 0); 2598 } catch (PackageManager.NameNotFoundException e) { 2599 // Ignore 2600 } 2601 Assert.assertNotNull(packageName + " should be installed", info); 2602 } 2603 2604 private void ensurePackageIsNotInstalled(String packageName) { 2605 runShellCommand("pm uninstall " + packageName); 2606 PackageInfo info = null; 2607 try { 2608 info = sPm.getPackageInfo(packageName, /* flags */ 0); 2609 } catch (PackageManager.NameNotFoundException e) { 2610 // Expected 2611 } 2612 Assert.assertNull(packageName + " shouldn't be installed", info); 2613 } 2614 2615 private void addPreferredActivity() { 2616 final IntentFilter filter = new IntentFilter( 2617 "android.intent.action.APP_ENUMERATION_PREFERRED_ACTIVITY"); 2618 final ComponentName[] candidates = {new ComponentName(TARGET_PREFERRED_ACTIVITY, 2619 ACTIVITY_CLASS_DUMMY_ACTIVITY)}; 2620 SystemUtil.runWithShellPermissionIdentity(() -> { 2621 sPm.addPreferredActivity(filter, IntentFilter.MATCH_ADJUSTMENT_NORMAL, 2622 candidates, candidates[0]); 2623 }, SET_PREFERRED_APPLICATIONS); 2624 } 2625 2626 private void clearPreferredActivity() { 2627 SystemUtil.runWithShellPermissionIdentity(() -> { 2628 sPm.clearPackagePreferredActivities(TARGET_PREFERRED_ACTIVITY); 2629 }, SET_PREFERRED_APPLICATIONS); 2630 } 2631 } 2632