Add display focus e2e platform test scenarios

Bug: 371094633
Flag: com.android.window.flags.enable_display_focus_in_shell_transitions
Test: atest OpenAndFocusTest
Test: atest ClickAndFocusTest
Test: atest DragAndKeepFocusTest
Test: atest MoveToNextDisplayAndFocusTest
Test: atest CloseThenMoveFocusTest
Change-Id: I2d67bb68697f6ad6a9c5c89320d28ae1578f0457
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/ClickAndFocusTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/ClickAndFocusTest.kt
new file mode 100644
index 0000000..4697cde
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/ClickAndFocusTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional.fundamentals.focus
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.ClickAndFocus
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [ClickAndFocus]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class ClickAndFocusTest : ClickAndFocus()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/CloseThenMoveFocusTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/CloseThenMoveFocusTest.kt
new file mode 100644
index 0000000..0bec61e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/CloseThenMoveFocusTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional.fundamentals.focus
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.CloseThenMoveFocus
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [CloseThenMoveFocus]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class CloseThenMoveFocusTest : CloseThenMoveFocus()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/DragAndKeepFocusTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/DragAndKeepFocusTest.kt
new file mode 100644
index 0000000..dcc1023
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/DragAndKeepFocusTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional.fundamentals.focus
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.DragAndKeepFocus
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [DragAndKeppFocus]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class DragAndKeepFocusTest : DragAndKeepFocus()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/MoveToNextDisplayAndFocusTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/MoveToNextDisplayAndFocusTest.kt
new file mode 100644
index 0000000..017b72d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/MoveToNextDisplayAndFocusTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional.fundamentals.focus
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.MoveToNextDisplayAndFocus
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [MoveToNextDisplayAndFocus]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class MoveToNextDisplayAndFocusTest : MoveToNextDisplayAndFocus()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/OpenAndFocusTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/OpenAndFocusTest.kt
new file mode 100644
index 0000000..f2e5bb4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/fundamentals/focus/OpenAndFocusTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional.fundamentals.focus
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.OpenAndFocus
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [OpenAndFocus]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class OpenAndFocusTest : OpenAndFocus()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ClickAndFocus.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ClickAndFocus.kt
new file mode 100644
index 0000000..3610273
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ClickAndFocus.kt
@@ -0,0 +1,84 @@
+/* Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.platform.test.annotations.EnableFlags
+import android.tools.PlatformConsts.DEFAULT_DISPLAY
+import android.tools.traces.parsers.WindowManagerStateHelper
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.META_META_ON
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.KeyEventHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.shared.desktopmode.DesktopState
+import org.junit.After import org.junit.Assume import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import platform.test.desktop.SimulatedConnectedDisplayTestRule
+
+
+/**
+ * Base scenario test to test if the display if focused after click.
+ */
+@Ignore("Test Base Class")
+@EnableFlags(
+    Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS,
+)
+abstract class ClickAndFocus() {
+    private val wmHelper = WindowManagerStateHelper(getInstrumentation())
+
+    private val device = UiDevice.getInstance(getInstrumentation())
+    private val testAppInMainDisplay = DesktopModeAppHelper(SimpleAppHelper(getInstrumentation()))
+    private val testAppInExternalDisplay =
+            DesktopModeAppHelper(MailAppHelper(getInstrumentation()))
+    private val keyEventHelper = KeyEventHelper(getInstrumentation())
+
+    @get:Rule(order = 0) val connectedDisplayRule = SimulatedConnectedDisplayTestRule()
+
+    @Before
+    fun setup() {
+        connectedDisplayRule.setupTestDisplay()
+        Assume.assumeTrue(
+            DesktopState.fromContext(getInstrumentation().context)
+                .isDesktopModeSupportedOnDisplay(DEFAULT_DISPLAY)
+        )
+        // TODO(b/426420246): Use launchViaIntentOnDisplay
+        testAppInExternalDisplay.launchViaIntent(wmHelper)
+        testAppInExternalDisplay.moveToNextDisplayViaKeyboard(
+            wmHelper,
+            connectedDisplayRule.addedDisplays.first()
+        )
+        testAppInMainDisplay.launchViaIntent(wmHelper)
+    }
+
+    @Test
+    open fun clickAndFocus() {
+        testAppInExternalDisplay.clickCaption(wmHelper, device)
+        // Send minimize via keyboard and observe window to check display focus.
+        keyEventHelper.press(KEYCODE_MINUS, META_META_ON)
+    }
+
+    @After
+    fun teardown() {
+        testAppInMainDisplay.exit(wmHelper)
+        testAppInExternalDisplay.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseThenMoveFocus.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseThenMoveFocus.kt
new file mode 100644
index 0000000..f7123e2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseThenMoveFocus.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.platform.test.annotations.EnableFlags
+import android.tools.PlatformConsts.DEFAULT_DISPLAY
+import android.tools.traces.parsers.WindowManagerStateHelper
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.META_META_ON
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.KeyEventHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.shared.desktopmode.DesktopState
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import platform.test.desktop.SimulatedConnectedDisplayTestRule
+
+
+/**
+ * Base scenario test to test if the remaining window in other display is focused after the focused
+ * window is closed.
+ */
+@Ignore("Test Base Class")
+@EnableFlags(
+    Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS,
+)
+abstract class CloseThenMoveFocus() {
+    private val wmHelper = WindowManagerStateHelper(getInstrumentation())
+
+    private val device = UiDevice.getInstance(getInstrumentation())
+    private val testAppInMainDisplay = DesktopModeAppHelper(SimpleAppHelper(getInstrumentation()))
+    private val testAppInExternalDisplay =
+            DesktopModeAppHelper(MailAppHelper(getInstrumentation()))
+    private val keyEventHelper = KeyEventHelper(getInstrumentation())
+
+    @get:Rule(order = 0) val connectedDisplayRule = SimulatedConnectedDisplayTestRule()
+
+    @Before
+    fun setup() {
+        connectedDisplayRule.setupTestDisplay()
+        Assume.assumeTrue(
+            DesktopState.fromContext(getInstrumentation().context)
+                .isDesktopModeSupportedOnDisplay(DEFAULT_DISPLAY)
+        )
+        testAppInMainDisplay.enterDesktopMode(wmHelper, device)
+        // TODO(b/426420246): Use launchViaIntentOnDisplay
+        testAppInExternalDisplay.launchViaIntent(wmHelper)
+        testAppInExternalDisplay.moveToNextDisplayViaKeyboard(
+            wmHelper,
+            connectedDisplayRule.addedDisplays.first()
+        )
+        testAppInExternalDisplay.enterDesktopMode(wmHelper, device)
+    }
+
+    @Test
+    open fun closeThenMoveFocus() {
+        testAppInExternalDisplay.clickCaption(
+            wmHelper,
+            device,
+            connectedDisplayRule.addedDisplays.first()
+        )
+        testAppInExternalDisplay.closeDesktopApp(wmHelper, device)
+        // Send minimize via keyboard and observe window to check display focus.
+        keyEventHelper.press(KEYCODE_MINUS, META_META_ON)
+    }
+
+    @After
+    fun teardown() {
+        testAppInMainDisplay.exit(wmHelper)
+        testAppInExternalDisplay.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAndKeepFocus.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAndKeepFocus.kt
new file mode 100644
index 0000000..e5d0a92
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAndKeepFocus.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.graphics.Point
+import android.hardware.display.DisplayManager
+import android.platform.test.annotations.EnableFlags
+import android.tools.PlatformConsts.DEFAULT_DISPLAY
+import android.tools.traces.parsers.WindowManagerStateHelper
+import android.view.Display.DEFAULT_DISPLAY
+import android.view.DisplayInfo
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.META_META_ON
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.KeyEventHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.shared.desktopmode.DesktopState
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import platform.test.desktop.DesktopMouseTestRule
+import platform.test.desktop.SimulatedConnectedDisplayTestRule
+
+
+/**
+ * Base scenario test to test if the window dragged to other display still keeps the focus.
+ */
+@Ignore("Test Base Class")
+@EnableFlags(
+    Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS,
+)
+abstract class DragAndKeepFocus() {
+    private val wmHelper = WindowManagerStateHelper(getInstrumentation())
+
+    private val device = UiDevice.getInstance(getInstrumentation())
+    private val testAppInMainDisplay = DesktopModeAppHelper(SimpleAppHelper(getInstrumentation()))
+    private val testAppInExternalDisplay =
+            DesktopModeAppHelper(MailAppHelper(getInstrumentation()))
+    private val displayManager =
+        getInstrumentation().targetContext.getSystemService(DisplayManager::class.java)
+    private val keyEventHelper = KeyEventHelper(getInstrumentation())
+
+    @get:Rule(order = 0) val connectedDisplayRule = SimulatedConnectedDisplayTestRule()
+    @get:Rule(order = 1) val desktopMouseRule = DesktopMouseTestRule()
+
+    @Before
+    fun setup() {
+        connectedDisplayRule.setupTestDisplay()
+        Assume.assumeTrue(
+            DesktopState.fromContext(getInstrumentation().context)
+                .isDesktopModeSupportedOnDisplay(DEFAULT_DISPLAY)
+        )
+        testAppInMainDisplay.launchViaIntent(wmHelper)
+        testAppInExternalDisplay.launchViaIntent(wmHelper)
+    }
+
+    @Test
+    open fun dragAndKeepFocus() {
+        val captionBounds =
+            checkNotNull(
+                testAppInExternalDisplay.getCaptionForTheApp(wmHelper, device)?.visibleBounds
+            )
+        val dragCoords = Point(captionBounds.centerX(), captionBounds.centerY())
+
+        // Move cursor to designated drag point
+        desktopMouseRule.move(DEFAULT_DISPLAY, dragCoords.x, dragCoords.y)
+
+        // Start drag and move
+        desktopMouseRule.startDrag()
+        val displayInfo = DisplayInfo().also {
+            displayManager.getDisplay(
+                connectedDisplayRule.addedDisplays.first()
+            ).getDisplayInfo(it)
+        }
+        desktopMouseRule.move(
+            connectedDisplayRule.addedDisplays.first(),
+            displayInfo.appWidth / 2,
+            displayInfo.appHeight / 2,
+        )
+        desktopMouseRule.stopDrag()
+        wmHelper.StateSyncBuilder()
+            .withAppTransitionIdle(connectedDisplayRule.addedDisplays.first())
+            .waitForAndVerify()
+
+        // Send minimize via keyboard and observe window to check display focus.
+        keyEventHelper.press(KEYCODE_MINUS, META_META_ON)
+    }
+
+    @After
+    fun teardown() {
+        testAppInMainDisplay.exit(wmHelper)
+        testAppInExternalDisplay.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MoveToNextDisplayAndFocus.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MoveToNextDisplayAndFocus.kt
new file mode 100644
index 0000000..40cec79
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MoveToNextDisplayAndFocus.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.platform.test.annotations.EnableFlags
+import android.tools.PlatformConsts.DEFAULT_DISPLAY
+import android.tools.traces.parsers.WindowManagerStateHelper
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.META_META_ON
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.KeyEventHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.shared.desktopmode.DesktopState
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import platform.test.desktop.SimulatedConnectedDisplayTestRule
+
+
+/**
+ * Base scenario test to test if the window moved to next display via keyboard keeps the focus.
+ */
+@Ignore("Test Base Class")
+@EnableFlags(
+    Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS,
+)
+abstract class MoveToNextDisplayAndFocus() {
+    private val wmHelper = WindowManagerStateHelper(getInstrumentation())
+
+    private val device = UiDevice.getInstance(getInstrumentation())
+    private val testAppInMainDisplay = DesktopModeAppHelper(SimpleAppHelper(getInstrumentation()))
+    private val testAppInExternalDisplay =
+            DesktopModeAppHelper(MailAppHelper(getInstrumentation()))
+    private val keyEventHelper = KeyEventHelper(getInstrumentation())
+
+    @get:Rule(order = 0) val connectedDisplayRule = SimulatedConnectedDisplayTestRule()
+
+    @Before
+    fun setup() {
+        connectedDisplayRule.setupTestDisplay()
+        Assume.assumeTrue(
+            DesktopState.fromContext(getInstrumentation().context)
+                .isDesktopModeSupportedOnDisplay(DEFAULT_DISPLAY)
+        )
+        testAppInMainDisplay.launchViaIntent(wmHelper)
+        testAppInExternalDisplay.launchViaIntent(wmHelper)
+    }
+
+    @Test
+    open fun moveToNextDisplayAndFocus() {
+        testAppInExternalDisplay.moveToNextDisplayViaKeyboard(
+            wmHelper,
+            connectedDisplayRule.addedDisplays.first()
+        )
+
+        // Send minimize via keyboard and observe window to check display focus.
+        keyEventHelper.press(KEYCODE_MINUS, META_META_ON)
+    }
+
+    @After
+    fun teardown() {
+        testAppInMainDisplay.exit(wmHelper)
+        testAppInExternalDisplay.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAndFocus.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAndFocus.kt
new file mode 100644
index 0000000..42062ee
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAndFocus.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.platform.test.annotations.EnableFlags
+import android.tools.PlatformConsts.DEFAULT_DISPLAY
+import android.tools.traces.parsers.WindowManagerStateHelper
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.META_META_ON
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.KeyEventHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.shared.desktopmode.DesktopState
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import platform.test.desktop.SimulatedConnectedDisplayTestRule
+
+
+/**
+ * Base scenario test to test if newly opened window gets focus.
+ */
+@Ignore("Test Base Class")
+@EnableFlags(
+    Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS,
+)
+abstract class OpenAndFocus() {
+    private val wmHelper = WindowManagerStateHelper(getInstrumentation())
+
+    private val device = UiDevice.getInstance(getInstrumentation())
+    private val testAppInMainDisplay = DesktopModeAppHelper(SimpleAppHelper(getInstrumentation()))
+    private val testAppInExternalDisplay =
+            DesktopModeAppHelper(MailAppHelper(getInstrumentation()))
+    private val keyEventHelper = KeyEventHelper(getInstrumentation())
+
+    @get:Rule(order = 0) val connectedDisplayRule = SimulatedConnectedDisplayTestRule()
+
+    @Before
+    fun setup() {
+        connectedDisplayRule.setupTestDisplay()
+        Assume.assumeTrue(
+            DesktopState.fromContext(getInstrumentation().context)
+                .isDesktopModeSupportedOnDisplay(DEFAULT_DISPLAY)
+        )
+        testAppInMainDisplay.launchViaIntent(wmHelper)
+    }
+
+    @Test
+    open fun openAndFocus() {
+        // TODO(b/426420246): Use launchViaIntentOnDisplay
+        testAppInExternalDisplay.launchViaIntent(wmHelper)
+        testAppInExternalDisplay.moveToNextDisplayViaKeyboard(
+            wmHelper,
+            connectedDisplayRule.addedDisplays.first()
+        )
+
+        // Send minimize via keyboard and observe window to check display focus.
+        keyEventHelper.press(KEYCODE_MINUS, META_META_ON)
+    }
+
+    @After
+    fun teardown() {
+        testAppInMainDisplay.exit(wmHelper)
+        testAppInExternalDisplay.exit(wmHelper)
+    }
+}
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index 09d87a9..995326e 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -32,6 +32,7 @@
 import android.tools.helpers.SYSTEMUI_PACKAGE
 import android.tools.traces.parsers.WindowManagerStateHelper
 import android.tools.traces.wm.WindowingMode
+import android.view.Display.DEFAULT_DISPLAY
 import android.view.KeyEvent.KEYCODE_D
 import android.view.KeyEvent.KEYCODE_DPAD_DOWN
 import android.view.KeyEvent.KEYCODE_DPAD_UP
@@ -596,7 +597,7 @@
         wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
     }
 
-    fun exitDesktopModeToFullScreenWithAppHeader(wmHelper:WindowManagerStateHelper) {
+    fun exitDesktopModeToFullScreenWithAppHeader(wmHelper: WindowManagerStateHelper) {
         val openMenuButton = getDesktopAppViewByRes(OPEN_MENU_BUTTON)
         openMenuButton?.click()
         wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
@@ -611,7 +612,7 @@
         wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
     }
 
-    fun exitDesktopModeToSplitScreenWithAppHeader(wmHelper:WindowManagerStateHelper) {
+    fun exitDesktopModeToSplitScreenWithAppHeader(wmHelper: WindowManagerStateHelper) {
         val openMenuButton = getDesktopAppViewByRes(OPEN_MENU_BUTTON)
         openMenuButton?.click()
         wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
@@ -676,6 +677,22 @@
         }
     }
 
+    fun clickCaption(
+        wmHelper: WindowManagerStateHelper,
+        device: UiDevice,
+        displayId: Int = DEFAULT_DISPLAY
+    ) {
+        val caption = checkNotNull(getCaptionForTheApp(wmHelper, device)) {
+           "Unable to find caption"
+        }
+        caption.click()
+        wmHelper
+            .StateSyncBuilder()
+            .withAppTransitionIdle(displayId)
+            .withTopVisibleApp(innerHelper)
+            .waitForAndVerify()
+    }
+
     private fun getDesktopAppViewByRes(viewResId: String): UiObject2 =
         DeviceHelpers.waitForObj(By.res(SYSTEMUI_PACKAGE, viewResId), TIMEOUT)