Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e9a0386 authored by Lingyu Feng's avatar Lingyu Feng
Browse files

Prevent activity being launched on a display where canHostTasks()

returns false

Bug: 417098352
Flag: com.android.window.flags.enable_mirror_display_no_activity
Test: ActivityTaskSupervisorTests
Change-Id: I440bc08274fc656e60dda2b520f97ffed527e2b9
parent b9cffe82
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1793,8 +1793,10 @@ public class ActivityOptions extends ComponentOptions {
    /**
     * Sets the id of the display where the activity should be launched.
     * An app can launch activities on public displays or displays where the app already has
     * activities. Otherwise, trying to launch on a private display or providing an invalid display
     * id will result in an exception.
     * activities. Otherwise, trying to launch on a display for which
     * {@link android.app.ActivityManager#isActivityStartAllowedOnDisplay(Context, int, Intent)}
     * returns {@code false} (such as a private display or providing an invalid display id) will
     * result in an exception.
     * <p>
     * Setting launch display id will be ignored on devices that don't have
     * {@link android.content.pm.PackageManager#FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS}.
+8 −0
Original line number Diff line number Diff line
@@ -1277,6 +1277,14 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
            return false;
        }

        if (DesktopExperienceFlags.ENABLE_MIRROR_DISPLAY_NO_ACTIVITY.isTrue()) {
            if (!displayContent.mDisplay.canHostTasks()) {
                Slog.w(TAG, "Launch on display check: activity launch is not allowed on a "
                        + "display that cannot host tasks");
                return false;
            }
        }

        // Check if the caller has enough privileges to embed activities and launch to private
        // displays.
        final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+26 −1
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase {
     * Ensures that a trusted display can launch arbitrary activity and an untrusted display can't.
     */
    @Test
    public void testDisplayCanLaunchActivities() {
    public void testDisplayCanLaunchActivities_trustedDisplay() {
        final Display display = mDisplayContent.mDisplay;
        // An empty info without FLAG_ALLOW_EMBEDDED.
        final ActivityInfo activityInfo = new ActivityInfo();
@@ -355,6 +355,31 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase {
        assertThat(allowedOnUntrusted).isFalse();
    }

    /**
     * Ensures that an arbitrary activity can be launched on a display the can host tasks, and
     * cannot be launched on a display that cannot host tasks.
     */
    @EnableFlags(Flags.FLAG_ENABLE_MIRROR_DISPLAY_NO_ACTIVITY)
    @Test
    public void testDisplayCanLaunchActivities_canHostTasksDisplay() {
        final Display display = mDisplayContent.mDisplay;
        // An empty info without FLAG_ALLOW_EMBEDDED.
        final ActivityInfo activityInfo = new ActivityInfo();
        final int callingPid = 12345;
        final int callingUid = 12345;
        spyOn(display);

        doReturn(true).when(display).canHostTasks();
        final boolean allowedOnCanHostTasks = mSupervisor.isCallerAllowedToLaunchOnDisplay(
                callingPid, callingUid, display.getDisplayId(), activityInfo);
        assertThat(allowedOnCanHostTasks).isTrue();

        doReturn(false).when(display).canHostTasks();
        final boolean allowedOnCannotHostTasks = mSupervisor.isCallerAllowedToLaunchOnDisplay(
                callingPid, callingUid, display.getDisplayId(), activityInfo);
        assertThat(allowedOnCannotHostTasks).isFalse();
    }

    /**
     * Verifies that process state will be updated with pending top without activity state change.
     * E.g. switch focus between resumed activities in multi-window mode.