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.server.wm; 18 19 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20 import static android.app.AppOpsManager.MODE_ALLOWED; 21 import static android.app.AppOpsManager.MODE_ERRORED; 22 import static android.server.wm.BuildUtils.HW_TIMEOUT_MULTIPLIER; 23 import static android.server.wm.ShellCommandHelper.executeShellCommand; 24 import static android.server.wm.UiDeviceUtils.pressHomeButton; 25 import static android.server.wm.backgroundactivity.common.CommonComponents.EVENT_NOTIFIER_EXTRA; 26 import static android.view.Display.DEFAULT_DISPLAY; 27 28 import static com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow; 29 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 30 31 import static com.google.common.truth.Truth.assertThat; 32 import static com.google.common.truth.Truth.assertWithMessage; 33 import static com.google.common.truth.TruthJUnit.assume; 34 35 import android.Manifest; 36 import android.app.ActivityOptions; 37 import android.app.BroadcastOptions; 38 import android.app.PendingIntent; 39 import android.app.RemoteAction; 40 import android.app.UiAutomation; 41 import android.appwidget.AppWidgetHost; 42 import android.appwidget.AppWidgetManager; 43 import android.content.ComponentName; 44 import android.content.Context; 45 import android.content.Intent; 46 import android.content.pm.PackageManager; 47 import android.content.pm.ResolveInfo; 48 import android.content.pm.UserInfo; 49 import android.graphics.Bitmap; 50 import android.graphics.drawable.Icon; 51 import android.os.Bundle; 52 import android.os.RemoteException; 53 import android.os.ResultReceiver; 54 import android.os.SystemClock; 55 import android.os.UserHandle; 56 import android.os.UserManager; 57 import android.platform.test.annotations.AsbSecurityTest; 58 import android.platform.test.annotations.Presubmit; 59 import android.platform.test.annotations.RequiresFlagsDisabled; 60 import android.platform.test.annotations.RequiresFlagsEnabled; 61 import android.platform.test.flag.junit.CheckFlagsRule; 62 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 63 import android.provider.Settings; 64 import android.server.wm.backgroundactivity.appa.Components; 65 import android.server.wm.backgroundactivity.common.CommonComponents.Event; 66 import android.server.wm.backgroundactivity.common.EventReceiver; 67 import android.util.Log; 68 import android.view.textclassifier.TextClassification; 69 70 import androidx.test.filters.FlakyTest; 71 import androidx.test.platform.app.InstrumentationRegistry; 72 import androidx.test.uiautomator.By; 73 import androidx.test.uiautomator.BySelector; 74 import androidx.test.uiautomator.UiDevice; 75 import androidx.test.uiautomator.UiObject2; 76 import androidx.test.uiautomator.Until; 77 78 import com.android.bedstead.harrier.BedsteadJUnit4; 79 import com.android.bedstead.harrier.DeviceState; 80 import com.android.bedstead.harrier.annotations.RequireDoesNotHaveFeature; 81 import com.android.bedstead.harrier.annotations.RequireFeature; 82 import com.android.compatibility.common.util.AppOpsUtils; 83 import com.android.modules.utils.build.SdkLevel; 84 import com.android.window.flags.Flags; 85 86 import org.junit.ClassRule; 87 import org.junit.Ignore; 88 import org.junit.Rule; 89 import org.junit.Test; 90 import org.junit.runner.RunWith; 91 92 import java.util.List; 93 import java.util.concurrent.TimeoutException; 94 95 /** 96 * This class covers all test cases for starting/blocking background activities. 97 * As instrumentation tests started by shell are allowlisted to allow starting background activity, 98 * tests can't be done in this app alone. 99 * Hence, there are 2 extra apps, appA and appB. This class will send commands to appA/appB, for 100 * example, send a broadcast to appA and ask it to start a background activity, and we will monitor 101 * the result and see if it starts an activity successfully. 102 */ 103 @Presubmit 104 @RunWith(BedsteadJUnit4.class) 105 public class BackgroundActivityLaunchTest extends BackgroundActivityTestBase { 106 107 @Rule 108 public final CheckFlagsRule mCheckFlagsRule = 109 DeviceFlagsValueProvider.createCheckFlagsRule(); 110 111 @ClassRule 112 @Rule 113 public static final DeviceState sDeviceState = new DeviceState(); 114 115 private static final String TAG = "BackgroundActivityLaunchTest"; 116 117 private static final Icon EMPTY_ICON = Icon.createWithBitmap( 118 Bitmap.createBitmap(8, 8, Bitmap.Config.ARGB_8888)); 119 120 private static final long ACTIVITY_BG_START_GRACE_PERIOD_MS = 10 * 1000; 121 private static final int ACTIVITY_START_TIMEOUT_MS = 5000; 122 private static final int ACTIVITY_NOT_RESUMED_TIMEOUT_MS = 5000; 123 124 /** 125 * Tests can be executed as soon as the device has booted. When that happens the broadcast queue 126 * is long and it takes some time to process the broadcast we just sent. 127 */ 128 private static final int BROADCAST_DELIVERY_TIMEOUT_MS = 60000; 129 public static final Bundle SEND_OPTIONS_ALLOW_BAL = ActivityOptions.makeBasic() 130 .setPendingIntentBackgroundActivityStartMode( 131 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED).toBundle(); 132 public static final Bundle SEND_BROADCAST_OPTIONS_ALLOW_BAL = BroadcastOptions.makeBasic() 133 .setPendingIntentBackgroundActivityStartMode( 134 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED).toBundle(); 135 public static final Bundle CREATE_OPTIONS_DENY_BAL = 136 ActivityOptions.makeBasic().setPendingIntentCreatorBackgroundActivityStartMode( 137 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED).toBundle(); 138 public static final Bundle CREATE_OPTIONS_ALLOW_BAL = 139 ActivityOptions.makeBasic().setPendingIntentCreatorBackgroundActivityStartMode( 140 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED).toBundle(); 141 142 @Test testBackgroundActivityBlocked()143 public void testBackgroundActivityBlocked() throws Exception { 144 // Start AppA background activity and blocked 145 sendBroadcastAndWait(APP_A.SIMPLE_BROADCAST_RECEIVER); 146 startBackgroundActivity(APP_A); 147 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 148 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 149 } 150 151 @Test testBackgroundActivityBlockedInStartNextMatchingActivity()152 public void testBackgroundActivityBlockedInStartNextMatchingActivity() throws TimeoutException { 153 EventReceiver receiver = new EventReceiver( 154 Event.APP_A_LAUNCHER_MOVING_TO_BACKGROUND_ACTIVITY); 155 Intent intent = new Intent("StartNextMatchingActivityAction"); 156 intent.setComponent(APP_A.START_NEXT_MATCHING_ACTIVITY); 157 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 158 intent.putExtra(EVENT_NOTIFIER_EXTRA, receiver.getNotifier()); 159 mContext.startActivity(intent); 160 receiver.waitForEventOrThrow(ACTIVITY_START_TIMEOUT_MS); 161 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 162 } 163 164 @Test testStartBgActivity_usingStartActivitiesFromBackgroundPermission()165 public void testStartBgActivity_usingStartActivitiesFromBackgroundPermission() 166 throws Exception { 167 // Disable SAW app op for shell, since that can also allow starting activities from bg. 168 grantSystemAlertWindow(SHELL_PACKAGE, false); 169 170 // Launch the activity via a shell command, this way the system doesn't have info on which 171 // app launched the activity and thus won't use instrumentation privileges to launch it. But 172 // the shell has the START_ACTIVITIES_FROM_BACKGROUND permission, so we expect it to 173 // succeed. 174 // See testBackgroundActivityBlocked() for a case where an app without the 175 // START_ACTIVITIES_FROM_BACKGROUND permission is blocked from launching the activity from 176 // the background. 177 launchActivity(APP_A.BACKGROUND_ACTIVITY); 178 179 // If the activity launches, it means the START_ACTIVITIES_FROM_BACKGROUND permission works. 180 assertWithMessage("Launched activity should be at the top") 181 .that(mWmState.getTopActivityName(0)) 182 .isEqualTo(ComponentNameUtils.getActivityName(APP_A.BACKGROUND_ACTIVITY)); 183 } 184 185 @Test testBackgroundActivity_withinGracePeriodAndSdk33_isNotBlocked()186 public void testBackgroundActivity_withinGracePeriodAndSdk33_isNotBlocked() throws Exception { 187 // Start AppA foreground activity 188 startActivity(APP_A_33.FOREGROUND_ACTIVITY); 189 // Don't press home button to avoid stop app switches 190 mContext.sendBroadcast(new Intent(APP_A_33.FOREGROUND_ACTIVITY_ACTIONS.FINISH_ACTIVITY)); 191 mWmState.waitAndAssertActivityRemoved(APP_A_33.FOREGROUND_ACTIVITY); 192 startBackgroundActivity(APP_A_33); 193 assertActivityFocused(APP_A_33.BACKGROUND_ACTIVITY); 194 } 195 196 @Test testBackgroundActivity_withinASMGracePeriod_isBlocked()197 public void testBackgroundActivity_withinASMGracePeriod_isBlocked() throws Exception { 198 assumeSdkNewerThanUpsideDownCake(); 199 // Start AppA foreground activity 200 startActivity(APP_A.FOREGROUND_ACTIVITY); 201 // Don't press home button to avoid stop app switches 202 mContext.sendBroadcast(new Intent(APP_A.FOREGROUND_ACTIVITY_ACTIONS.FINISH_ACTIVITY)); 203 mWmState.waitAndAssertActivityRemoved(APP_A.FOREGROUND_ACTIVITY); 204 startBackgroundActivity(APP_A); 205 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 206 } 207 208 @Test 209 @FlakyTest(bugId = 297339382) testBackgroundActivity_withinBalAfterAsmGracePeriod_isBlocked()210 public void testBackgroundActivity_withinBalAfterAsmGracePeriod_isBlocked() 211 throws Exception { 212 assumeSdkNewerThanUpsideDownCake(); 213 // Start AppA foreground activity 214 startActivity(APP_A.FOREGROUND_ACTIVITY); 215 // Don't press home button to avoid stop app switches 216 mContext.sendBroadcast(new Intent(APP_A.FOREGROUND_ACTIVITY_ACTIONS.FINISH_ACTIVITY)); 217 mWmState.waitAndAssertActivityRemoved(APP_A.FOREGROUND_ACTIVITY); 218 Thread.sleep(1000 * 5); 219 startBackgroundActivity(APP_A); 220 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 221 } 222 223 @Test testBackgroundActivityWhenSystemAlertWindowGranted_isNotBlocked()224 public void testBackgroundActivityWhenSystemAlertWindowGranted_isNotBlocked() 225 throws Exception { 226 grantSystemAlertWindow(APP_A_33); 227 228 // Start AppA background activity successfully as the package has SAW 229 startBackgroundActivity(APP_A_33); 230 assertActivityFocused(APP_A_33.BACKGROUND_ACTIVITY); 231 } 232 233 @Test testBackgroundActivityBlockedWhenForegroundActivityNotTop()234 public void testBackgroundActivityBlockedWhenForegroundActivityNotTop() throws Exception { 235 assumeSdkNewerThanUpsideDownCake(); 236 237 startActivity(APP_A.FOREGROUND_ACTIVITY); 238 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, APP_B.FOREGROUND_ACTIVITY)); 239 mWmState.waitForValidState(APP_B.FOREGROUND_ACTIVITY); 240 mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY); 241 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 242 APP_B.FOREGROUND_ACTIVITY, 243 APP_A.FOREGROUND_ACTIVITY); 244 245 // Start AppA background activity fails as AppA not on top of stack 246 startBackgroundActivity(APP_A); 247 mWmState.waitForValidState(APP_A.BACKGROUND_ACTIVITY); 248 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 249 APP_B.FOREGROUND_ACTIVITY, 250 APP_A.FOREGROUND_ACTIVITY); 251 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 252 } 253 254 @Test testBackgroundActivityNotBlockedWhenForegroundActivityTop()255 public void testBackgroundActivityNotBlockedWhenForegroundActivityTop() throws Exception { 256 startActivity(APP_A.FOREGROUND_ACTIVITY); 257 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 258 259 // Start AppA background activity successfully in new task as there's a foreground activity 260 startBackgroundActivity(APP_A); 261 mWmState.waitForValidState(APP_A.BACKGROUND_ACTIVITY); 262 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 263 assertTaskStackHasComponents(APP_A.BACKGROUND_ACTIVITY, APP_A.BACKGROUND_ACTIVITY); 264 } 265 266 @Test testBackgroundActivityWhenForegroundActivityNotTopUsingSdk33_IsNotBlocked()267 public void testBackgroundActivityWhenForegroundActivityNotTopUsingSdk33_IsNotBlocked() 268 throws Exception { 269 startActivity(APP_A_33.FOREGROUND_ACTIVITY); 270 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A_33, APP_B.FOREGROUND_ACTIVITY)); 271 mWmState.waitForValidState(APP_B.FOREGROUND_ACTIVITY); 272 assertTaskStackHasComponents(APP_A_33.FOREGROUND_ACTIVITY, 273 APP_B.FOREGROUND_ACTIVITY, 274 APP_A_33.FOREGROUND_ACTIVITY); 275 276 // Start AppA background activity successfully as there's a foreground activity 277 startBackgroundActivity(APP_A_33); 278 mWmState.waitForValidState(APP_A_33.BACKGROUND_ACTIVITY); 279 assertTaskStackHasComponents(APP_A_33.FOREGROUND_ACTIVITY, 280 APP_B.FOREGROUND_ACTIVITY, 281 APP_A_33.FOREGROUND_ACTIVITY); 282 assertTaskStackHasComponents(APP_A_33.BACKGROUND_ACTIVITY, APP_A_33.BACKGROUND_ACTIVITY); 283 } 284 285 @Test testActivityNotBlockedWhenForegroundActivityLaunch()286 public void testActivityNotBlockedWhenForegroundActivityLaunch() throws Exception { 287 // Start foreground activity, and foreground activity able to launch background activity 288 // successfully 289 startActivity(APP_A.FOREGROUND_ACTIVITY); 290 291 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, APP_A.BACKGROUND_ACTIVITY)); 292 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 293 294 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 295 APP_A.BACKGROUND_ACTIVITY, 296 APP_A.FOREGROUND_ACTIVITY); 297 } 298 299 @Test testActivityBroughtToTopOfTaskWhenLaunchedInTheBackground()300 public void testActivityBroughtToTopOfTaskWhenLaunchedInTheBackground() throws Exception { 301 // Start foreground activity, and foreground activity able to launch background activity 302 // successfully 303 startActivity(APP_A.FOREGROUND_ACTIVITY); 304 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 305 // We can't resume app switching after pressing home button, otherwise the grace period 306 // will allow the starts. 307 pressHomeAndWaitHomeResumed(); 308 309 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, APP_A.BACKGROUND_ACTIVITY)); 310 311 assertActivityNotFocused(APP_A.FOREGROUND_ACTIVITY); 312 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 313 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 314 APP_A.BACKGROUND_ACTIVITY, 315 APP_A.FOREGROUND_ACTIVITY); 316 } 317 318 @Test testActivityBlockedFromBgActivityInFgTask()319 public void testActivityBlockedFromBgActivityInFgTask() { 320 assumeSdkNewerThanUpsideDownCake(); 321 // Launch Activity A, B in the same task with different processes. 322 startActivity(APP_A.FOREGROUND_ACTIVITY); 323 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, APP_B.FOREGROUND_ACTIVITY)); 324 mWmState.waitForValidState(APP_B.FOREGROUND_ACTIVITY); 325 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 326 APP_B.FOREGROUND_ACTIVITY, 327 APP_A.FOREGROUND_ACTIVITY); 328 329 // Refresh last-stop-app-switch-time by returning to home and then make the task foreground. 330 pressHomeAndResumeAppSwitch(); 331 startActivityUnchecked(APP_A.FOREGROUND_ACTIVITY); 332 mWmState.waitForValidState(APP_B.FOREGROUND_ACTIVITY); 333 // As A is not visible, it can not start activities. 334 mContext.sendBroadcast(new Intent( 335 APP_A.FOREGROUND_ACTIVITY_ACTIONS.LAUNCH_BACKGROUND_ACTIVITIES) 336 .putExtra(APP_A.FOREGROUND_ACTIVITY_EXTRA.LAUNCH_INTENTS, 337 new Intent[]{ new Intent() 338 .setComponent(APP_A.BACKGROUND_ACTIVITY) 339 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) })); 340 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 341 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 342 APP_B.FOREGROUND_ACTIVITY, 343 APP_A.FOREGROUND_ACTIVITY); 344 } 345 346 @Test testActivityFromBgActivityInFgTaskSdk33_isNotBlocked()347 public void testActivityFromBgActivityInFgTaskSdk33_isNotBlocked() { 348 // Launch Activity A, B in the same task with different processes. 349 startActivity(APP_A_33.FOREGROUND_ACTIVITY); 350 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A_33, APP_B.FOREGROUND_ACTIVITY)); 351 mWmState.waitForValidState(APP_B.FOREGROUND_ACTIVITY); 352 assertTaskStackHasComponents(APP_A_33.FOREGROUND_ACTIVITY, 353 APP_B.FOREGROUND_ACTIVITY, 354 APP_A_33.FOREGROUND_ACTIVITY); 355 356 // Refresh last-stop-app-switch-time by returning to home and then make the task foreground. 357 pressHomeAndResumeAppSwitch(); 358 startActivityUnchecked(APP_A_33.FOREGROUND_ACTIVITY); 359 mWmState.waitForValidState(APP_B.FOREGROUND_ACTIVITY); 360 // Though process A is in background, it is in a visible Task (top is B) so it should be 361 // able to start activity successfully. 362 mContext.sendBroadcast(new Intent( 363 APP_A_33.FOREGROUND_ACTIVITY_ACTIONS.LAUNCH_BACKGROUND_ACTIVITIES) 364 .putExtra(APP_A_33.FOREGROUND_ACTIVITY_EXTRA.LAUNCH_INTENTS, 365 new Intent[]{ new Intent() 366 .setComponent(APP_A_33.BACKGROUND_ACTIVITY) 367 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) })); 368 mWmState.waitForValidState(APP_A_33.BACKGROUND_ACTIVITY); 369 mWmState.assertFocusedActivity( 370 "The background activity must be able to launch from a visible task", 371 APP_A_33.BACKGROUND_ACTIVITY); 372 } 373 374 @Test 375 @FlakyTest(bugId = 130800326) 376 @Ignore // TODO(b/145981637): Make this test work testActivityBlockedWhenForegroundActivityRestartsItself()377 public void testActivityBlockedWhenForegroundActivityRestartsItself() throws Exception { 378 // Start AppA foreground activity 379 startActivity(APP_A.FOREGROUND_ACTIVITY, 380 APP_A.FOREGROUND_ACTIVITY_EXTRA.RELAUNCH_FOREGROUND_ACTIVITY_EXTRA); 381 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 382 383 // The foreground activity will be paused but will attempt to restart itself in onPause() 384 pressHomeAndResumeAppSwitch(); 385 386 assertActivityNotFocused(APP_A.FOREGROUND_ACTIVITY); 387 } 388 389 @Test testSecondActivityNotBlockedWhenForegroundActivityLaunch()390 public void testSecondActivityNotBlockedWhenForegroundActivityLaunch() throws Exception { 391 // Start AppA foreground activity, which will immediately launch one activity 392 // and then the second. 393 startActivity(APP_A.FOREGROUND_ACTIVITY); 394 395 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, APP_A.BACKGROUND_ACTIVITY)); 396 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 397 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, APP_A.SECOND_BACKGROUND_ACTIVITY)); 398 assertActivityFocused(APP_A.SECOND_BACKGROUND_ACTIVITY); 399 400 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 401 APP_A.SECOND_BACKGROUND_ACTIVITY, 402 APP_A.BACKGROUND_ACTIVITY, 403 APP_A.FOREGROUND_ACTIVITY); 404 } 405 406 @Test testSecondActivityBlockedWhenBackgroundActivityLaunch()407 public void testSecondActivityBlockedWhenBackgroundActivityLaunch() throws Exception { 408 startActivity(APP_A.FOREGROUND_ACTIVITY); 409 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 410 // We can't resume app switching after pressing home button, otherwise the grace period 411 // will allow the starts. 412 pressHomeAndWaitHomeResumed(); 413 414 // The activity, now in the background, will attempt to start 2 activities in quick 415 // succession 416 mContext.sendBroadcast(getLaunchActivitiesBroadcast(APP_A, 417 APP_A.BACKGROUND_ACTIVITY, 418 APP_A.SECOND_BACKGROUND_ACTIVITY)); 419 420 // There should be 2 activities in the background (not focused) INITIALIZING 421 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 422 assertActivityNotFocused(APP_A.SECOND_BACKGROUND_ACTIVITY); 423 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, 424 APP_A.SECOND_BACKGROUND_ACTIVITY, 425 APP_A.BACKGROUND_ACTIVITY, 426 APP_A.FOREGROUND_ACTIVITY); 427 } 428 429 @Test testPendingIntentActivityBlocked()430 public void testPendingIntentActivityBlocked() throws Exception { 431 TestServiceClient serviceA = getTestService(APP_A); 432 TestServiceClient serviceB = getTestService(APP_B); 433 434 // Cannot start activity by pending intent, as both appA and appB are in background 435 PendingIntent pi = generatePendingIntent(serviceA, APP_A.BACKGROUND_ACTIVITY); 436 sendPendingIntent(pi, serviceB); 437 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 438 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 439 } 440 441 @Test testPendingIntentActivity_whenSenderAllowsBal_isNotBlocked()442 public void testPendingIntentActivity_whenSenderAllowsBal_isNotBlocked() throws Exception { 443 // creator (appa) is not privileged 444 grantSystemAlertWindow(APP_A, false); 445 // sender (appb) is privileged, and grants 446 grantSystemAlertWindow(APP_B); 447 448 startPendingIntentSenderActivity(APP_A, APP_B, /* allowBalBySender */ true); 449 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 450 assertTaskStackHasComponents(APP_A.BACKGROUND_ACTIVITY, APP_A.BACKGROUND_ACTIVITY); 451 } 452 453 @Test 454 @RequiresFlagsDisabled(Flags.FLAG_BAL_DONT_BRING_EXISTING_BACKGROUND_TASK_STACK_TO_FG) testPI_onlyCreatorAllowsBALInSameTask_isNotBlocked()455 public void testPI_onlyCreatorAllowsBALInSameTask_isNotBlocked() throws Exception { 456 // creator (appa) is not privileged 457 grantSystemAlertWindow(APP_A, false); 458 // sender (appb) is privileged, and grants 459 grantSystemAlertWindow(APP_B); 460 461 startActivity(APP_A.FOREGROUND_ACTIVITY); 462 463 pressHomeAndWaitHomeResumed(); 464 465 TestServiceClient serviceB = getTestService(APP_B); 466 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY, 467 CREATE_OPTIONS_ALLOW_BAL); 468 TestServiceClient serviceA = getTestService(APP_A); 469 // send the pending intent in the same task. 470 serviceA.sendPendingIntentWithActivity(pi, Bundle.EMPTY); 471 472 assertActivityFocused(APP_B.BACKGROUND_ACTIVITY); 473 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_B.BACKGROUND_ACTIVITY, 474 APP_A.FOREGROUND_ACTIVITY); 475 } 476 477 @Test 478 @RequiresFlagsEnabled(Flags.FLAG_BAL_DONT_BRING_EXISTING_BACKGROUND_TASK_STACK_TO_FG) testPI_onlyCreatorAllowsBALInSameTask_isBlocked()479 public void testPI_onlyCreatorAllowsBALInSameTask_isBlocked() throws Exception { 480 // sender (appa) is not privileged 481 grantSystemAlertWindow(APP_A, false); 482 // creator (appb) is privileged, and grants 483 grantSystemAlertWindow(APP_B); 484 485 startActivity(APP_A.FOREGROUND_ACTIVITY); 486 487 pressHomeAndWaitHomeResumed(); 488 489 TestServiceClient serviceB = getTestService(APP_B); 490 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY, 491 CREATE_OPTIONS_ALLOW_BAL); 492 TestServiceClient serviceA = getTestService(APP_A); 493 // send the pending intent in the same task. 494 serviceA.sendPendingIntentWithActivity(pi, Bundle.EMPTY); 495 496 assertActivityNotFocused(APP_B.BACKGROUND_ACTIVITY); 497 } 498 499 @Test 500 @RequiresFlagsEnabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) 501 @RequiresFlagsDisabled(Flags.FLAG_BAL_DONT_BRING_EXISTING_BACKGROUND_TASK_STACK_TO_FG) testPI_onlyCreatorAllowsBALwithOptIn_isNotBlocked()502 public void testPI_onlyCreatorAllowsBALwithOptIn_isNotBlocked() throws Exception { 503 // sender (appa) is not privileged 504 grantSystemAlertWindow(APP_A, false); 505 // creator (appb) is privileged, and grants 506 grantSystemAlertWindow(APP_B); 507 508 startActivity(APP_A.FOREGROUND_ACTIVITY); 509 510 pressHomeAndWaitHomeResumed(); 511 512 TestServiceClient serviceB = getTestService(APP_B); 513 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY, 514 CREATE_OPTIONS_ALLOW_BAL); 515 TestServiceClient serviceA = getTestService(APP_A); 516 serviceA.sendPendingIntentWithActivity(pi, Bundle.EMPTY); 517 518 assertActivityFocused(APP_B.BACKGROUND_ACTIVITY); 519 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_B.BACKGROUND_ACTIVITY, 520 APP_A.FOREGROUND_ACTIVITY); 521 } 522 523 @Test 524 @RequiresFlagsEnabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) 525 @RequiresFlagsDisabled(Flags.FLAG_BAL_DONT_BRING_EXISTING_BACKGROUND_TASK_STACK_TO_FG) testPI_onlyCreatorAllowsBALwithoutOptInSdk33_isNotBlocked()526 public void testPI_onlyCreatorAllowsBALwithoutOptInSdk33_isNotBlocked() throws Exception { 527 // A (privileged) creates PI, B (non-privileged) sends PI from BG, C is started 528 grantSystemAlertWindow(APP_A_33); 529 grantSystemAlertWindow(APP_B, false); 530 531 startActivity(APP_B.FOREGROUND_ACTIVITY); 532 533 pressHomeAndWaitHomeResumed(); 534 535 TestServiceClient servicePiCreator = getTestService(APP_A_33); 536 PendingIntent pi = servicePiCreator.generatePendingIntent(APP_C.BACKGROUND_ACTIVITY, 537 CREATE_OPTIONS_ALLOW_BAL); 538 TestServiceClient servicePiSender = getTestService(APP_B); 539 servicePiSender.sendPendingIntentWithActivity(pi, Bundle.EMPTY); 540 541 assertActivityFocused(APP_C.BACKGROUND_ACTIVITY); 542 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_C.BACKGROUND_ACTIVITY, 543 APP_B.FOREGROUND_ACTIVITY); 544 } 545 546 @Test 547 @RequiresFlagsEnabled({Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR, 548 Flags.FLAG_BAL_DONT_BRING_EXISTING_BACKGROUND_TASK_STACK_TO_FG}) testPI_onlyCreatorAllowsBALwithOptIn_isStartedInBackground()549 public void testPI_onlyCreatorAllowsBALwithOptIn_isStartedInBackground() throws Exception { 550 // sender (appa) is not privileged 551 grantSystemAlertWindow(APP_A, false); 552 // creator (appb) is privileged, and grants 553 grantSystemAlertWindow(APP_B); 554 555 startActivity(APP_A.FOREGROUND_ACTIVITY); 556 557 pressHomeAndWaitHomeResumed(); 558 559 TestServiceClient serviceB = getTestService(APP_B); 560 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY, 561 CREATE_OPTIONS_ALLOW_BAL); 562 TestServiceClient serviceA = getTestService(APP_A); 563 serviceA.sendPendingIntentWithActivity(pi, Bundle.EMPTY); 564 565 assertActivityNotFocused(APP_B.BACKGROUND_ACTIVITY); 566 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_B.BACKGROUND_ACTIVITY, 567 APP_A.FOREGROUND_ACTIVITY); 568 } 569 570 @Test testPI_onlySenderAllowsBALwithoutOptInForResult_isNotBlocked()571 public void testPI_onlySenderAllowsBALwithoutOptInForResult_isNotBlocked() throws Exception { 572 startActivity(APP_A.FOREGROUND_ACTIVITY); 573 574 TestServiceClient serviceB = getTestService(APP_B); 575 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY); 576 TestServiceClient serviceA = getTestService(APP_A); 577 // there is no explicit opt-in, but using sendPendingIntentForResult implicitly grants 578 serviceA.sendPendingIntentWithActivityForResult(pi, Bundle.EMPTY); 579 580 assertActivityFocused(APP_B.BACKGROUND_ACTIVITY); 581 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_B.BACKGROUND_ACTIVITY, 582 APP_A.FOREGROUND_ACTIVITY); 583 } 584 585 @Test 586 @RequiresFlagsEnabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) testPI_onlyCreatorAllowsBALwithoutOptInForResult_isBlocked()587 public void testPI_onlyCreatorAllowsBALwithoutOptInForResult_isBlocked() throws Exception { 588 // creator (appb) is privileged, and grants 589 grantSystemAlertWindow(APP_B); 590 591 startActivity(APP_A.FOREGROUND_ACTIVITY); 592 pressHomeAndWaitHomeResumed(); 593 594 TestServiceClient serviceB = getTestService(APP_B); 595 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY); 596 TestServiceClient serviceA = getTestService(APP_A); 597 // sendPendingIntentForResult does not opt in the creator of the PI 598 serviceA.sendPendingIntentWithActivityForResult(pi, Bundle.EMPTY); 599 600 assertActivityNotFocused(APP_B.BACKGROUND_ACTIVITY); 601 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 602 } 603 604 @Test 605 @RequiresFlagsEnabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) testPI_onlySenderAllowsBALwithoutOptInIntentSender_isNotBlocked()606 public void testPI_onlySenderAllowsBALwithoutOptInIntentSender_isNotBlocked() throws Exception { 607 startActivity(APP_A.FOREGROUND_ACTIVITY); 608 609 TestServiceClient serviceB = getTestService(APP_B); 610 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY); 611 TestServiceClient serviceA = getTestService(APP_A); 612 // there is no explicit opt-in, but using IntentSender.sendIntent implicitly grants 613 serviceA.sendIntentSender(pi.getIntentSender(), Bundle.EMPTY); 614 615 assertActivityFocused(APP_B.BACKGROUND_ACTIVITY); 616 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 617 assertTaskStackHasComponents(APP_B.BACKGROUND_ACTIVITY, APP_B.BACKGROUND_ACTIVITY); 618 } 619 620 @Test 621 @RequiresFlagsEnabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) testPI_onlyCreatorAllowsBALwithoutOptIn_isBlocked()622 public void testPI_onlyCreatorAllowsBALwithoutOptIn_isBlocked() throws Exception { 623 // sender (appa) is not privileged 624 grantSystemAlertWindow(APP_A, false); 625 // creator (appb) is privileged, and grants 626 grantSystemAlertWindow(APP_B); 627 628 startActivity(APP_A.FOREGROUND_ACTIVITY); 629 630 pressHomeAndWaitHomeResumed(); 631 632 TestServiceClient serviceB = getTestService(APP_B); 633 PendingIntent pi = serviceB.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY); 634 TestServiceClient serviceA = getTestService(APP_A); 635 serviceA.sendPendingIntentWithActivity(pi, Bundle.EMPTY); 636 637 assertActivityNotFocused(APP_B.BACKGROUND_ACTIVITY); 638 } 639 640 @Test testPendingIntentActivity_whenSenderDoesNotAllowBal_isBlocked()641 public void testPendingIntentActivity_whenSenderDoesNotAllowBal_isBlocked() throws Exception { 642 // creator (appa) is not privileged 643 grantSystemAlertWindow(APP_A, false); 644 // sender (appb) is privileged, but revokes 645 grantSystemAlertWindow(APP_B); 646 647 startPendingIntentSenderActivity(APP_A, APP_B, /* allowBalBySender */ false); 648 649 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 650 } 651 652 @Test testPI_appAIsForegroundDenyCreatorPrivilege_launchAppB_isBlocked()653 public void testPI_appAIsForegroundDenyCreatorPrivilege_launchAppB_isBlocked() 654 throws Exception { 655 // Start AppA foreground activity 656 startActivity(APP_A.FOREGROUND_ACTIVITY); 657 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 658 659 // App A create a PendingIntent with ActivityOption that denies PendingIntent sender to use 660 // creator's privilege to launch itself. The PendingIntent itself is to launch App B. Since 661 // App B is in the background, it should be blocked even though the creator (App A) is in 662 // the foreground. 663 TestServiceClient serviceA = getTestService(APP_A); 664 PendingIntent pi = serviceA.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY, 665 CREATE_OPTIONS_DENY_BAL); 666 TestServiceClient serviceB = getTestService(APP_B); 667 sendPendingIntent(pi, serviceB); 668 assertActivityNotFocused(APP_B.FOREGROUND_ACTIVITY); 669 } 670 671 @Test 672 @SuppressWarnings("MissingFail") // TODO(b/320664730) expect Exception after V release testPI_appAIsFgDenyCreatorPrivilege_appBTryOverrideCreatorPrivilege_isBlocked()673 public void testPI_appAIsFgDenyCreatorPrivilege_appBTryOverrideCreatorPrivilege_isBlocked() 674 throws Exception { 675 // Start AppB foreground activity 676 startActivity(APP_A.FOREGROUND_ACTIVITY); 677 assertTaskStackHasComponents(APP_A.FOREGROUND_ACTIVITY, APP_A.FOREGROUND_ACTIVITY); 678 679 // App A create a PendingIntent with ActivityOption that denies PendingIntent sender to use 680 // creator's privilege to launch itself. The PendingIntent itself is to launch App B. 681 // App B is in the background, it should be blocked even though the creator (App A) is in 682 // the foreground. However, The sender (App B) also tries to override the creator option by 683 // setting the creator option from the sender side. This should not work. Creator option 684 // cannot be set from the sender side. 685 TestServiceClient serviceA = getTestService(APP_A); 686 PendingIntent pi = 687 serviceA.generatePendingIntent(APP_B.BACKGROUND_ACTIVITY, 688 CREATE_OPTIONS_DENY_BAL); 689 TestServiceClient serviceB = getTestService(APP_B); 690 try { 691 serviceB.sendPendingIntent(pi, CREATE_OPTIONS_ALLOW_BAL); 692 } catch (IllegalArgumentException e) { 693 assertThat(e).hasMessageThat() 694 .contains("pendingIntentCreatorBackgroundActivityStartMode"); 695 // If sending the PendingIntent failed because we detected a mismatch in the bundle, 696 // the result should be the same as suppressing the start (just earlier). 697 } 698 assertActivityNotFocused(APP_B.FOREGROUND_ACTIVITY); 699 } 700 701 @Test 702 @RequiresFlagsDisabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) testPendingIntentActivity_appAIsForeground_isNotBlocked()703 public void testPendingIntentActivity_appAIsForeground_isNotBlocked() throws Exception { 704 // Start AppA foreground activity 705 Components appA = APP_A; 706 startActivity(appA.FOREGROUND_ACTIVITY); 707 assertTaskStackHasComponents(appA.FOREGROUND_ACTIVITY, appA.FOREGROUND_ACTIVITY); 708 709 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 710 // activity in App A 711 TestServiceClient serviceA = getTestService(appA); 712 PendingIntent pi = generatePendingIntent(serviceA, appA.BACKGROUND_ACTIVITY); 713 TestServiceClient serviceB = getTestService(APP_B); 714 sendPendingIntent(pi, serviceB); 715 716 assertActivityFocused(appA.BACKGROUND_ACTIVITY); 717 assertTaskStackHasComponents(appA.FOREGROUND_ACTIVITY, appA.FOREGROUND_ACTIVITY); 718 assertTaskStackHasComponents(appA.BACKGROUND_ACTIVITY, appA.BACKGROUND_ACTIVITY); 719 } 720 721 @Test 722 @RequiresFlagsEnabled(Flags.FLAG_BAL_REQUIRE_OPT_IN_BY_PENDING_INTENT_CREATOR) testPendingIntentActivity_appAIsForeground_isBlocked()723 public void testPendingIntentActivity_appAIsForeground_isBlocked() throws Exception { 724 // Start AppA foreground activity 725 Components appA = APP_A; 726 startActivity(appA.FOREGROUND_ACTIVITY); 727 assertTaskStackHasComponents(appA.FOREGROUND_ACTIVITY, appA.FOREGROUND_ACTIVITY); 728 729 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 730 // activity in App A 731 TestServiceClient serviceA = getTestService(appA); 732 PendingIntent pi = generatePendingIntent(serviceA, appA.BACKGROUND_ACTIVITY); 733 TestServiceClient serviceB = getTestService(APP_B); 734 sendPendingIntent(pi, serviceB); 735 736 assertActivityNotFocused(appA.BACKGROUND_ACTIVITY); 737 } 738 739 @Test testPendingIntentActivity_appA33IsForeground_isNotBlocked()740 public void testPendingIntentActivity_appA33IsForeground_isNotBlocked() throws Exception { 741 // Start AppA foreground activity 742 Components appA = APP_A_33; 743 startActivity(appA.FOREGROUND_ACTIVITY); 744 assertTaskStackHasComponents(appA.FOREGROUND_ACTIVITY, appA.FOREGROUND_ACTIVITY); 745 746 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 747 // activity in App A 748 TestServiceClient serviceA = getTestService(appA); 749 PendingIntent pi = generatePendingIntent(serviceA, appA.BACKGROUND_ACTIVITY); 750 TestServiceClient serviceB = getTestService(APP_B); 751 sendPendingIntent(pi, serviceB); 752 753 assertActivityFocused(appA.BACKGROUND_ACTIVITY); 754 assertTaskStackHasComponents(appA.FOREGROUND_ACTIVITY, appA.FOREGROUND_ACTIVITY); 755 assertTaskStackHasComponents(appA.BACKGROUND_ACTIVITY, appA.BACKGROUND_ACTIVITY); 756 } 757 758 @Test testPendingIntentBroadcastActivity_appBIsForeground_isBlocked()759 public void testPendingIntentBroadcastActivity_appBIsForeground_isBlocked() throws Exception { 760 // Start AppB foreground activity 761 startActivity(APP_B.FOREGROUND_ACTIVITY); 762 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 763 764 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 765 // activity in App A 766 TestServiceClient serviceA = getTestService(APP_A); 767 PendingIntent pi = generatePendingIntent(serviceA, APP_A.BACKGROUND_ACTIVITY); 768 TestServiceClient serviceB = getTestService(APP_B); 769 sendPendingIntent(pi, serviceB); 770 771 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 772 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 773 } 774 775 @Test testPendingIntentBroadcastActivity_appBIsForegroundAndSdk33_isNotBlocked()776 public void testPendingIntentBroadcastActivity_appBIsForegroundAndSdk33_isNotBlocked() 777 throws Exception { 778 779 // setup 780 TestServiceClient appATestService = getTestService(APP_A); 781 TestServiceClient appBTestService = getTestService(APP_B_33); 782 783 // create PI in appA 784 PendingIntent pi = generatePendingIntent(appATestService, APP_A.BACKGROUND_ACTIVITY); 785 786 // bring app B to foreground 787 startActivity(APP_B_33.FOREGROUND_ACTIVITY); 788 789 // pass to appB and send PI 790 appBTestService.sendPendingIntent(pi, null); 791 792 // assert that start succeeded 793 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 794 } 795 796 @Test 797 @SuppressWarnings("MissingFail") // TODO(b/320664730) expect Exception after V release testPendingIntentBroadcastActivity_appBIsForegroundAndTryPassBalOnIntent_isBlocked()798 public void testPendingIntentBroadcastActivity_appBIsForegroundAndTryPassBalOnIntent_isBlocked() 799 throws Exception { 800 // Start AppB foreground activity 801 startActivity(APP_B.FOREGROUND_ACTIVITY); 802 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 803 804 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 805 // activity in App A. 806 // ALLOW_BAL_EXTRA_ON_PENDING_INTENT will trigger AppA (the creator) to try to allow BAL on 807 // behalf of the sender by adding the BAL option to the Intent's extras, which should have 808 // no effect. 809 TestServiceClient serviceA = getTestService(APP_A); 810 try { 811 PendingIntent pi = serviceA.generatePendingIntent(APP_A.BACKGROUND_ACTIVITY, 812 SEND_OPTIONS_ALLOW_BAL); 813 TestServiceClient serviceB = getTestService(APP_B); 814 sendPendingIntent(pi, serviceB); 815 } catch (IllegalArgumentException e) { 816 assertThat(e).hasMessageThat().contains("pendingIntentBackgroundActivityStartMode"); 817 // If generating the PendingIntent failed because we detected a mismatch in the bundle, 818 // the result should be the same as suppressing the start (just earlier). 819 } 820 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 821 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 822 } 823 824 @Test 825 @SuppressWarnings("MissingFail") // TODO(b/320664730) expect Exception after V release testPendingIntentBroadcastActivity_appBIsFgAndTryPassBalOnIntentWithNullBundleOnPendingIntent_isBlocked()826 public void testPendingIntentBroadcastActivity_appBIsFgAndTryPassBalOnIntentWithNullBundleOnPendingIntent_isBlocked() 827 throws Exception { 828 // Start AppB foreground activity 829 startActivity(APP_B.FOREGROUND_ACTIVITY); 830 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 831 832 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 833 // activity in App A 834 TestServiceClient serviceA = getTestService(APP_A); 835 try { 836 PendingIntent pi = serviceA.generatePendingIntent(APP_A.BACKGROUND_ACTIVITY, 837 SEND_OPTIONS_ALLOW_BAL); 838 TestServiceClient serviceB = getTestService(APP_B); 839 serviceB.sendPendingIntent(pi, null); 840 } catch (IllegalArgumentException e) { 841 assertThat(e).hasMessageThat().contains("pendingIntentBackgroundActivityStartMode"); 842 // If generating the PendingIntent failed because we detected a mismatch in the bundle, 843 // the result should be the same as suppressing the start (just earlier). 844 } 845 846 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 847 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 848 } 849 850 @Test testPendingIntentBroadcastActivity_appBIsForegroundAndAllowsBal_isNotBlocked()851 public void testPendingIntentBroadcastActivity_appBIsForegroundAndAllowsBal_isNotBlocked() 852 throws Exception { 853 // setup 854 TestServiceClient appATestService = getTestService(APP_A); 855 TestServiceClient appBTestService = getTestService(APP_B); 856 857 // create PI in appA 858 PendingIntent pi = generatePendingIntent(appATestService, APP_A.BACKGROUND_ACTIVITY); 859 860 // bring app B to foreground 861 startActivity(APP_B.FOREGROUND_ACTIVITY); 862 863 // pass to appB and send PI 864 appBTestService.sendPendingIntent(pi, SEND_OPTIONS_ALLOW_BAL); 865 866 // assert that start succeeded 867 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 868 } 869 870 @Test testPendingIntentBroadcastTimeout_noDelay_isNotBlocked()871 public void testPendingIntentBroadcastTimeout_noDelay_isNotBlocked() throws Exception { 872 TestServiceClient serviceA = getTestService(APP_A); 873 TestServiceClient serviceB = getTestService(APP_B); 874 875 // Start AppB foreground activity 876 startActivity(APP_B.FOREGROUND_ACTIVITY); 877 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 878 879 EventReceiver receiver = new EventReceiver(Event.BROADCAST_RECEIVED); 880 PendingIntent pi = serviceA.generatePendingIntentBroadcast(APP_A.SIMPLE_BROADCAST_RECEIVER, 881 receiver.getNotifier()); 882 // PI broadcast should create token to allow serviceA to start activities later 883 serviceB.sendPendingIntent(pi, SEND_BROADCAST_OPTIONS_ALLOW_BAL); 884 receiver.waitForEventOrThrow(ACTIVITY_START_TIMEOUT_MS); 885 886 // Grace period is still active. 887 startBackgroundActivity(serviceA, APP_A); 888 889 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 890 assertTaskStackHasComponents(APP_A.BACKGROUND_ACTIVITY, APP_A.BACKGROUND_ACTIVITY); 891 } 892 893 @Test testPendingIntentBroadcastTimeout_delay1s_isNotBlocked()894 public void testPendingIntentBroadcastTimeout_delay1s_isNotBlocked() throws Exception { 895 TestServiceClient serviceA = getTestService(APP_A); 896 TestServiceClient serviceB = getTestService(APP_B); 897 898 // Start AppB foreground activity 899 startActivity(APP_B.FOREGROUND_ACTIVITY); 900 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 901 902 EventReceiver receiver = new EventReceiver(Event.BROADCAST_RECEIVED); 903 PendingIntent pi = serviceA.generatePendingIntentBroadcast(APP_A.SIMPLE_BROADCAST_RECEIVER, 904 receiver.getNotifier()); 905 // PI broadcast should create token to allow serviceA to start activities later 906 serviceB.sendPendingIntent(pi, SEND_BROADCAST_OPTIONS_ALLOW_BAL); 907 receiver.waitForEventOrThrow(ACTIVITY_START_TIMEOUT_MS); 908 909 SystemClock.sleep(1000); 910 // Grace period is still active. 911 startBackgroundActivity(serviceA, APP_A); 912 913 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 914 assertTaskStackHasComponents(APP_A.BACKGROUND_ACTIVITY, APP_A.BACKGROUND_ACTIVITY); 915 } 916 917 @Test testPendingIntentBroadcastTimeout_delay12s_isBlocked()918 public void testPendingIntentBroadcastTimeout_delay12s_isBlocked() throws Exception { 919 // This test is testing that activity start is blocked after broadcast allowlist token 920 // timeout. Before the timeout, the start would be allowed because app B (the PI sender) was 921 // in the foreground during PI send, so app A (the PI creator) would have 922 // (10s * hw_multiplier) to start background activity starts. 923 TestServiceClient serviceA = getTestService(APP_A); 924 TestServiceClient serviceB = getTestService(APP_B); 925 926 // Start AppB foreground activity 927 startActivity(APP_B.FOREGROUND_ACTIVITY); 928 assertTaskStackHasComponents(APP_B.FOREGROUND_ACTIVITY, APP_B.FOREGROUND_ACTIVITY); 929 930 EventReceiver receiver = new EventReceiver(Event.BROADCAST_RECEIVED); 931 PendingIntent pi = serviceA.generatePendingIntentBroadcast(APP_A.SIMPLE_BROADCAST_RECEIVER, 932 receiver.getNotifier()); 933 // PI broadcast should create token to allow serviceA to start activities later 934 serviceB.sendPendingIntent(pi, SEND_BROADCAST_OPTIONS_ALLOW_BAL); 935 receiver.waitForEventOrThrow(ACTIVITY_START_TIMEOUT_MS); 936 937 SystemClock.sleep(12000L * HW_TIMEOUT_MULTIPLIER); 938 // Grace period is expired. 939 startBackgroundActivity(serviceA, APP_A); 940 941 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 942 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 943 } 944 945 @Test testPendingIntentBroadcast_appBIsBackground_isBlocked()946 public void testPendingIntentBroadcast_appBIsBackground_isBlocked() throws Exception { 947 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 948 // activity in App A. Since AppB is not in foreground and has no other privileges to start 949 // an activity the start should be blocked. 950 TestServiceClient serviceA = getTestService(APP_A); 951 PendingIntent pi = serviceA.generatePendingIntentBroadcast(APP_B.FOREGROUND_ACTIVITY); 952 TestServiceClient serviceB = getTestService(APP_B); 953 serviceB.sendPendingIntent(pi, null); 954 955 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 956 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 957 } 958 959 /** 960 * Returns a list of alive users on the device 961 */ getAliveUsers()962 private List<UserInfo> getAliveUsers() { 963 // Setting the CREATE_USERS permission in AndroidManifest.xml has no effect when the test 964 // is run through the CTS harness, so instead adopt it as a shell permission. We use 965 // the CREATE_USERS permission instead of MANAGE_USERS because the shell can never use 966 // MANAGE_USERS. 967 UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); 968 uiAutomation.adoptShellPermissionIdentity(Manifest.permission.CREATE_USERS); 969 List<UserInfo> userList = mContext.getSystemService(UserManager.class).getAliveUsers(); 970 uiAutomation.dropShellPermissionIdentity(); 971 return userList; 972 } 973 974 /** 975 * Removes the guest user from the device if present 976 */ removeGuestUser()977 private void removeGuestUser() { 978 List<UserInfo> userList = getAliveUsers(); 979 for (UserInfo info : userList) { 980 if (info.isGuest()) { 981 removeUser(info.id); 982 // Device is only allowed to have one alive guest user, so stop if it's found 983 break; 984 } 985 } 986 } 987 988 /** 989 * Removes a user from the device given their ID 990 */ removeUser(int userId)991 private void removeUser(int userId) { 992 executeShellCommand(String.format("pm remove-user %d", userId)); 993 } 994 995 @Test testDeviceOwner()996 public void testDeviceOwner() throws Exception { 997 assume().withMessage("Device doesn't support FEATURE_DEVICE_ADMIN") 998 .that(mContext.getPackageManager() 999 .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) 1000 .isTrue(); 1001 1002 // Remove existing guest user. The device may already have a guest present if it is 1003 // configured with config_guestUserAutoCreated. 1004 // 1005 // In production flow the DO can only be created before device provisioning finishes 1006 // (e.g. during SUW), and we make sure the guest user in only created after the device 1007 // provision is finished. Ideally this test would use the provisioning flow and Device 1008 // Owner (DO) creation in a similar manner as that of production flow. 1009 removeGuestUser(); 1010 1011 // This test might be running as current user (on devices that use headless system user 1012 // mode), so it needs to get the context for the system user. 1013 Context context = runWithShellPermissionIdentity( 1014 () -> mContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0), 1015 INTERACT_ACROSS_USERS); 1016 1017 String doComponent = APP_A.SIMPLE_ADMIN_RECEIVER.flattenToString(); 1018 Log.d(TAG, "Setting DO as " + doComponent); 1019 String cmd = "dpm set-device-owner --user " + UserHandle.USER_SYSTEM + " " + doComponent; 1020 try { 1021 String cmdResult = runShellCommandOrThrow(cmd); 1022 assertWithMessage("Result of '%s'", cmd).that(cmdResult).contains("Success"); 1023 } catch (AssertionError e) { 1024 // If failed to set the device owner, stop proceeding to the test case. 1025 // Log the error info so that we can investigate further in the future. 1026 Log.d(TAG, "Failed to set device owner.", e); 1027 String cmdResult = runShellCommandOrThrow("pm list user"); 1028 Log.d(TAG, "users: " + cmdResult); 1029 cmdResult = runShellCommandOrThrow("dpm list-owner"); 1030 Log.d(TAG, "device owners: " + cmdResult); 1031 assume().withMessage("This test needs to be able to set device owner") 1032 .fail(); 1033 } 1034 1035 // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start 1036 // activity in App A 1037 Log.d(TAG, "Launching " + APP_A.BACKGROUND_ACTIVITY + " on " + context.getUser()); 1038 // Must run with IAC permission as it might be a context from other user 1039 runWithShellPermissionIdentity(() -> startBackgroundActivity(APP_A), INTERACT_ACROSS_USERS); 1040 1041 // Waits for final hoop in AppA to start looking for activity 1042 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 1043 assertTaskStackHasComponents(APP_A.BACKGROUND_ACTIVITY, APP_A.BACKGROUND_ACTIVITY); 1044 } 1045 1046 @Test testAppCannotStartBgActivityAfterHomeButton()1047 public void testAppCannotStartBgActivityAfterHomeButton() throws Exception { 1048 startActivity(APP_A.RELAUNCHING_ACTIVITY); 1049 1050 // Click home button, and test app activity onPause() will try to start a background 1051 // activity, but we expect this will be blocked BAL logic in system, as app cannot start 1052 // any background activity even within grace period after pressing home button. 1053 pressHomeAndWaitHomeResumed(); 1054 1055 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1056 } 1057 1058 // Check picture-in-picture(PIP) won't allow to start BAL after pressing home. 1059 @Test testPipCannotStartAfterHomeButton()1060 public void testPipCannotStartAfterHomeButton() throws Exception { 1061 startActivity(APP_A.PIP_ACTIVITY); 1062 1063 // Click home button, and test app activity onPause() will trigger pip window, 1064 // test will will try to start background activity, but we expect the background activity 1065 // will be blocked even the app has a visible pip window, as we do not allow background 1066 // activity to be started after pressing home button. 1067 pressHomeAndWaitHomeResumed(); 1068 1069 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1070 } 1071 1072 @Test 1073 @AsbSecurityTest(cveBugId = 271576718) testPipCannotStartFromBackground()1074 public void testPipCannotStartFromBackground() throws Exception { 1075 startActivity(APP_A.LAUNCH_INTO_PIP_ACTIVITY); 1076 1077 pressHomeAndWaitHomeResumed(); 1078 assertActivityNotFocused(APP_A.LAUNCH_INTO_PIP_ACTIVITY); 1079 1080 Intent broadcast = new Intent(APP_A.LAUNCH_INTO_PIP_ACTIONS.LAUNCH_INTO_PIP); 1081 mContext.sendBroadcast(broadcast); 1082 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1083 1084 assertPinnedStackDoesNotExist(); 1085 } 1086 1087 // Check that a presentation on a virtual display won't allow BAL after pressing home. 1088 @Test testPrivateVirtualDisplayCannotStartAfterHomeButton()1089 public void testPrivateVirtualDisplayCannotStartAfterHomeButton() throws Exception { 1090 startActivity(APP_A.VIRTUAL_DISPLAY_ACTIVITY); 1091 1092 // Click home button, and test app activity onPause() will trigger which tries to launch 1093 // the background activity. 1094 pressHomeAndWaitHomeResumed(); 1095 1096 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1097 } 1098 1099 // Check that a presentation on a virtual display won't allow BAL after pressing home. 1100 @Test testPublicVirtualDisplayCannotStartAfterHomeButton()1101 public void testPublicVirtualDisplayCannotStartAfterHomeButton() throws Exception { 1102 startActivity(APP_A.VIRTUAL_DISPLAY_ACTIVITY, 1103 APP_A.VIRTUAL_DISPLAY_ACTIVITY_EXTRA.USE_PUBLIC_PRESENTATION); 1104 1105 // Click home button, and test app activity onPause() will trigger which tries to launch 1106 // the background activity. 1107 pressHomeAndWaitHomeResumed(); 1108 1109 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1110 } 1111 1112 1113 // Test manage space pending intent created by system cannot bypass BAL check. 1114 @Test testManageSpacePendingIntentNoBalAllowed()1115 public void testManageSpacePendingIntentNoBalAllowed() throws Exception { 1116 TestServiceClient appATestService = getTestService(APP_A); 1117 runWithShellPermissionIdentity(() -> { 1118 runShellCommandOrThrow("cmd appops set " + APP_A.APP_PACKAGE_NAME 1119 + " android:manage_external_storage allow"); 1120 }); 1121 // Make sure AppA paused at least 10s so it can't start activity because of grace period. 1122 Thread.sleep(1000 * 10); 1123 appATestService.startManageSpaceActivity(); 1124 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1125 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 1126 } 1127 1128 @Test 1129 @RequireFeature(PackageManager.FEATURE_APP_WIDGETS) 1130 @RequireDoesNotHaveFeature(PackageManager.FEATURE_LEANBACK_ONLY) testAppWidgetConfigNoBalBypass()1131 public void testAppWidgetConfigNoBalBypass() throws Exception { 1132 // Click bind widget button and then go home screen so app A will enter background state 1133 // with bind widget ability. 1134 EventReceiver receiver = new EventReceiver(Event.APP_A_START_WIDGET_CONFIG_ACTIVITY); 1135 clickAllowBindWidget(APP_A, receiver.getNotifier()); 1136 pressHomeAndWaitHomeResumed(); 1137 1138 // After pressing home button, wait for appA to start widget config activity. 1139 receiver.waitForEventOrThrow(1000 * 30); 1140 1141 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1142 assertTaskStackIsEmpty(APP_A.BACKGROUND_ACTIVITY); 1143 } 1144 1145 @Test testBalOptInBindToService_whenOptedIn_allowsActivityStarts()1146 public void testBalOptInBindToService_whenOptedIn_allowsActivityStarts() { 1147 startActivityUnchecked(APP_C.BIND_SERVICE_ACTIVITY, 1148 "android.server.wm.backgroundactivity.appc.ALLOW_BAL"); 1149 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 1150 } 1151 1152 @Test testBalOptInBindToService_whenNotOptedIn_blocksActivityStarts()1153 public void testBalOptInBindToService_whenNotOptedIn_blocksActivityStarts() { 1154 startActivityUnchecked(APP_C.BIND_SERVICE_ACTIVITY); 1155 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1156 } 1157 1158 @Test testBalOptInBindToService_whenNotOptedInAndSdk33_allowsActivityStart()1159 public void testBalOptInBindToService_whenNotOptedInAndSdk33_allowsActivityStart() { 1160 startActivityUnchecked(APP_C_33.BIND_SERVICE_ACTIVITY); 1161 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 1162 } 1163 1164 @Test testActivityStartbyTextClassifier_appBInFg_allowsActivityStart()1165 public void testActivityStartbyTextClassifier_appBInFg_allowsActivityStart() throws Exception { 1166 TestServiceClient appATestService = getTestService(APP_A); 1167 TestServiceClient appBTestService = getTestService(APP_B); 1168 // create PI in appA 1169 PendingIntent pi = generatePendingIntent(appATestService, APP_A.BACKGROUND_ACTIVITY); 1170 1171 // app B in foreground 1172 startActivity(APP_B.FOREGROUND_ACTIVITY); 1173 // pass to appB and send PI 1174 TextClassification tc = new TextClassification.Builder() 1175 .addAction(new RemoteAction(EMPTY_ICON, "myAction", 1176 "classifiedContentDescription", pi)) 1177 .build(); 1178 appBTestService.sendByTextClassification(tc); 1179 1180 // assert that start succeeded 1181 assertActivityFocused(APP_A.BACKGROUND_ACTIVITY); 1182 } 1183 1184 @Test testActivityStartbyTextClassifier_appBInBg_blocksActivityStart()1185 public void testActivityStartbyTextClassifier_appBInBg_blocksActivityStart() throws Exception { 1186 TestServiceClient appATestService = getTestService(APP_A); 1187 TestServiceClient appBTestService = getTestService(APP_B); 1188 // create PI in appA 1189 PendingIntent pi = generatePendingIntent(appATestService, APP_A.BACKGROUND_ACTIVITY); 1190 1191 // app B not in FG 1192 // pass to appB and send PI 1193 TextClassification tc = new TextClassification.Builder() 1194 .addAction(new RemoteAction(EMPTY_ICON, "myAction", 1195 "classifiedContentDescription", pi)) 1196 .build(); 1197 appBTestService.sendByTextClassification(tc); 1198 1199 // assert that start is blocked 1200 assertActivityNotFocused(APP_A.BACKGROUND_ACTIVITY); 1201 } 1202 clickAllowBindWidget(Components app, ResultReceiver resultReceiver)1203 private void clickAllowBindWidget(Components app, ResultReceiver resultReceiver) 1204 throws Exception { 1205 // Create appWidgetId so we can send it to app, to request bind widget and start config 1206 // activity. 1207 UiDevice device = UiDevice.getInstance(mInstrumentation); 1208 AppWidgetHost appWidgetHost = new AppWidgetHost(mContext, 0); 1209 final int appWidgetId = appWidgetHost.allocateAppWidgetId(); 1210 Intent appWidgetIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); 1211 appWidgetIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 1212 appWidgetIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, 1213 app.WIDGET_PROVIDER); 1214 1215 Intent intent = new Intent(); 1216 intent.setComponent(app.WIDGET_CONFIG_TEST_ACTIVITY); 1217 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1218 intent.putExtra(Intent.EXTRA_INTENT, appWidgetIntent); 1219 intent.putExtra(EVENT_NOTIFIER_EXTRA, resultReceiver); 1220 mContext.startActivity(intent); 1221 1222 // Find settings package and bind widget activity and click the create button. 1223 String settingsPkgName = ""; 1224 PackageManager pm = mContext.getPackageManager(); 1225 List<ResolveInfo> ris = pm.queryIntentActivities(appWidgetIntent, 1226 PackageManager.MATCH_DEFAULT_ONLY); 1227 for (ResolveInfo ri : ris) { 1228 if (ri.activityInfo.name.contains("AllowBindAppWidgetActivity")) { 1229 settingsPkgName = ri.activityInfo.packageName; 1230 } 1231 } 1232 assertWithMessage("Cannot find settings app").that(settingsPkgName).isNotEmpty(); 1233 assertWithMessage("Unable to start AllowBindAppWidgetActivity") 1234 .that(device.wait(Until.hasObject(By.pkg(settingsPkgName)), 1000 * 10)).isTrue(); 1235 boolean buttonClicked = false; 1236 BySelector selector = By.clickable(true); 1237 List<UiObject2> objects = device.findObjects(selector); 1238 for (UiObject2 object : objects) { 1239 String objectText = object.getText(); 1240 if (objectText == null) { 1241 continue; 1242 } 1243 if (objectText.equalsIgnoreCase("CREATE") || objectText.equalsIgnoreCase("ALLOW")) { 1244 object.click(); 1245 buttonClicked = true; 1246 break; 1247 } 1248 } 1249 assertWithMessage("Create' button not found/clicked") 1250 .that(device.wait(Until.gone(By.pkg(settingsPkgName)), 1000 * 10) && buttonClicked) 1251 .isTrue(); 1252 1253 // Wait the bind widget activity goes away. 1254 waitUntilForegroundChanged(settingsPkgName, false, 1255 ACTIVITY_NOT_RESUMED_TIMEOUT_MS); 1256 } 1257 pressHomeAndWaitHomeResumed()1258 private void pressHomeAndWaitHomeResumed() { 1259 assumeSetupComplete(); 1260 pressHomeButton(); 1261 mWmState.waitForHomeActivityVisible(); 1262 mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY); 1263 } 1264 assumeSetupComplete()1265 private void assumeSetupComplete() { 1266 assume().that(Settings.Secure.getInt(mContext.getContentResolver(), 1267 Settings.Secure.USER_SETUP_COMPLETE, 0)).isEqualTo(1); 1268 } 1269 checkPackageResumed(String pkg)1270 private boolean checkPackageResumed(String pkg) { 1271 WindowManagerStateHelper helper = new WindowManagerStateHelper(); 1272 helper.computeState(); 1273 return ComponentName.unflattenFromString( 1274 helper.getFocusedActivity()).getPackageName().equals(pkg); 1275 } 1276 1277 // Return true if the state of the package is changed to target state. waitUntilForegroundChanged(String targetPkg, boolean toBeResumed, int timeout)1278 private boolean waitUntilForegroundChanged(String targetPkg, boolean toBeResumed, int timeout) 1279 throws Exception { 1280 long startTime = System.currentTimeMillis(); 1281 while (checkPackageResumed(targetPkg) != toBeResumed) { 1282 if (System.currentTimeMillis() - startTime < timeout) { 1283 Thread.sleep(100); 1284 } else { 1285 return false; 1286 } 1287 } 1288 return true; 1289 } 1290 assertActivityNotResumed(Components app)1291 private void assertActivityNotResumed(Components app) throws Exception { 1292 assertWithMessage("Test activity is resumed").that( 1293 waitUntilForegroundChanged(app.APP_PACKAGE_NAME, true, 1294 ACTIVITY_NOT_RESUMED_TIMEOUT_MS)).isFalse(); 1295 } 1296 pressHomeAndResumeAppSwitch()1297 private void pressHomeAndResumeAppSwitch() { 1298 // Press home key to ensure stopAppSwitches is called because the last-stop-app-switch-time 1299 // is a criteria of allowing background start. 1300 pressHomeButton(); 1301 // Resume the stopped state (it won't affect last-stop-app-switch-time) so we don't need to 1302 // wait extra time to prevent the next launch from being delayed. 1303 resumeAppSwitches(); 1304 mWmState.waitForHomeActivityVisible(); 1305 // Resuming app switches again after home became visible because the previous call might 1306 // have raced with pressHomeButton(). 1307 // TODO(b/155454710): Remove previous call after making sure all the tests don't depend on 1308 // the timing here. 1309 resumeAppSwitches(); 1310 } 1311 startPendingIntentSenderActivity(Components appToCreatePendingIntent, Components appToSendPendingIntent, boolean allowBal)1312 private void startPendingIntentSenderActivity(Components appToCreatePendingIntent, 1313 Components appToSendPendingIntent, boolean allowBal) throws Exception { 1314 TestServiceClient testServiceToCreatePendingIntent = 1315 getTestService(appToCreatePendingIntent); 1316 // Get a PendingIntent created by appToCreatePendingIntent. 1317 final PendingIntent pi; 1318 try { 1319 pi = generatePendingIntent(testServiceToCreatePendingIntent, 1320 appToCreatePendingIntent.BACKGROUND_ACTIVITY); 1321 } catch (Exception e) { 1322 throw new AssertionError(e); 1323 } 1324 1325 // Start app B's activity so it runs send() on PendingIntent created by app A. 1326 Intent secondIntent = new Intent(); 1327 secondIntent.setComponent(appToSendPendingIntent.START_PENDING_INTENT_ACTIVITY); 1328 secondIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1329 secondIntent.putExtra( 1330 appToSendPendingIntent.START_PENDING_INTENT_ACTIVITY_EXTRA.PENDING_INTENT, pi); 1331 secondIntent.putExtra( 1332 appToSendPendingIntent.START_PENDING_INTENT_ACTIVITY_EXTRA.START_BUNDLE, 1333 ActivityOptions.makeBasic().setPendingIntentBackgroundActivityStartMode( 1334 allowBal ? ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED 1335 : ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED) 1336 .toBundle()); 1337 mContext.startActivity(secondIntent); 1338 } 1339 1340 /** 1341 * Start the given activity in a new task. 1342 * 1343 * After starting the activity this method asserts that the activity is actually started and is 1344 * shown as the focused activity in the foreground. 1345 * 1346 * @param componentName activity to start 1347 * @param extraTrueNames (optional) names of extras that should be set to <code>true</code> 1348 */ startActivity(ComponentName componentName, String... extraTrueNames)1349 private void startActivity(ComponentName componentName, String... extraTrueNames) { 1350 startActivityUnchecked(componentName, extraTrueNames); 1351 assertActivityFocused(componentName); 1352 } 1353 1354 /** 1355 * Start the given activity in a new task. 1356 * 1357 * There is no check that the activity actually got started or that it is now in the foreground. 1358 * 1359 * @param componentName activity to start 1360 * @param extraTrueNames (optional) names of extras that should be set to <code>true</code> 1361 */ startActivityUnchecked(ComponentName componentName, String... extraTrueNames)1362 private void startActivityUnchecked(ComponentName componentName, String... extraTrueNames) { 1363 Intent intent = new Intent(); 1364 intent.setComponent(componentName); 1365 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1366 for (String extraTrueName : extraTrueNames) { 1367 intent.putExtra(extraTrueName, true); 1368 } 1369 mContext.startActivity(intent); 1370 } 1371 grantSystemAlertWindow(Components app)1372 private static void grantSystemAlertWindow(Components app) throws Exception { 1373 grantSystemAlertWindow(app, true); 1374 } 1375 grantSystemAlertWindow(Components app, boolean allow)1376 private static void grantSystemAlertWindow(Components app, boolean allow) throws Exception { 1377 grantSystemAlertWindow(app.APP_PACKAGE_NAME, allow); 1378 } 1379 grantSystemAlertWindow(String packageName, boolean allow)1380 private static void grantSystemAlertWindow(String packageName, boolean allow) throws Exception { 1381 final int mode = allow ? MODE_ALLOWED : MODE_ERRORED; 1382 final String opStr = "android:system_alert_window"; 1383 AppOpsUtils.setOpMode(packageName, opStr, mode); 1384 assertThat(AppOpsUtils.getOpMode(packageName, opStr)).isEqualTo(mode); 1385 } 1386 startBackgroundActivity(TestServiceClient service, Components app)1387 private static void startBackgroundActivity(TestServiceClient service, Components app) 1388 throws Exception { 1389 service.startActivityIntent(new Intent().setComponent(app.BACKGROUND_ACTIVITY) 1390 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 1391 } 1392 startBackgroundActivity(Components app)1393 private void startBackgroundActivity(Components app) throws Exception { 1394 startBackgroundActivity(getTestService(app), app); 1395 } 1396 sendBroadcastAndWait(ComponentName componentName)1397 void sendBroadcastAndWait(ComponentName componentName) throws Exception { 1398 EventReceiver receiver = new EventReceiver(Event.BROADCAST_RECEIVED); 1399 Intent intent = new Intent(); 1400 intent.setComponent(componentName); 1401 intent.putExtra(EVENT_NOTIFIER_EXTRA, receiver.getNotifier()); 1402 mContext.sendBroadcast(intent); 1403 receiver.waitForEventOrThrow(ACTIVITY_START_TIMEOUT_MS); 1404 } 1405 generatePendingIntent(TestServiceClient testService, ComponentName activity)1406 private static PendingIntent generatePendingIntent(TestServiceClient testService, 1407 ComponentName activity) throws RemoteException { 1408 return testService.generatePendingIntent(activity, null); 1409 } 1410 sendPendingIntent(PendingIntent pi, TestServiceClient service)1411 private static void sendPendingIntent(PendingIntent pi, TestServiceClient service) 1412 throws RemoteException { 1413 service.sendPendingIntent(pi, Bundle.EMPTY); 1414 } 1415 assumeSdkNewerThanUpsideDownCake()1416 static void assumeSdkNewerThanUpsideDownCake() { 1417 // Feature flag "ActivitySecurity__asm_restrictions_enabled" is set to 1 in 1418 // BackgroundActivityTestBase. For backward compatibility reasons, it is only enabled 1419 // for apps with targetSdkVersion starting Android V. 1420 // TODO remove this assumption after V released. 1421 assume().that(SdkLevel.isAtLeastV()).isTrue(); 1422 } 1423 } 1424