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

Commit e2f59993 authored by Lingyu Feng's avatar Lingyu Feng
Browse files

Do not start secondary home on display that cannot host tasks

The system server can crash with a SecurityException due to a race
condition when launching a secondary home activity. This crash occurs if
Display.canHostTasks() becomes false, but WindowManager has not yet
received the corresponding onDisplayChanged() event. This CL prevents
the crash by ensuring Display.canHostTasks() is checked before the
launch attempt.

Bug: 438030031
Test: RootWindowContainerTests
Flag: com.android.server.display.feature.flags.enable_display_content_mode_management
Flag: com.android.window.flags.enable_mirror_display_no_activity
Change-Id: I0957cdcef4dfc955d2b2e89d7dad72e29b28c215
parent 1a2a7e81
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1577,6 +1577,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            return false;
        }

        if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()
                && DesktopExperienceFlags.ENABLE_MIRROR_DISPLAY_NO_ACTIVITY.isTrue()) {
            if (!display.mDisplay.canHostTasks()) {
                // Can't launch home on display that cannot host tasks.
                return false;
            }
        }

        return true;
    }

+17 −0
Original line number Diff line number Diff line
@@ -1084,6 +1084,23 @@ public class RootWindowContainerTests extends WindowTestsBase {
        verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
    }

    /**
     * Tests that secondary home activity should not be resolved if display cannot host tasks.
     */
    @Test
    public void testStartSecondaryHomeOnDisplayCannotHostTasks() {
        // Create secondary displays.
        final TestDisplayContent secondDisplay =
                new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
        spyOn(secondDisplay.mDisplay);
        doReturn(false).when(secondDisplay.mDisplay).canHostTasks();

        mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
                secondDisplay.mDisplayId, true /* allowInstrumenting */, true /* fromHomeKey */);

        verify(mRootWindowContainer, never()).resolveSecondaryHomeActivity(anyInt(), any());
    }

    /**
     * Tests that when starting {@link ResolverActivity} for home, it should use the standard
     * activity type (in a new root task) so the order of back stack won't be broken.