• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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