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