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

Commit 36a06391 authored by Toshiki Kikuchi's avatar Toshiki Kikuchi
Browse files

Prevent misuse of getFocusedTaskOnDisplay

This CL makes getFocusedTaskOnDisplay to return only taskId instead of
full TaskInfo whose properties may be stale as this observer only
updates the cache when the focus changes.

Flag: com.android.window.flags.enable_block_non_desktop_display_window_drag_bugfix
Flag: com.android.window.flags.enable_desktop_first_top_fullscreen_bugfix
Bug: 436462692
Test: ShellDesktopStateImplTest
Test: DesktopTasksControllerTest
Change-Id: Ide32a0ac2bed020a922964228ce64c145dbf7dae
parent 3ca8828c
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1310,9 +1310,10 @@ public abstract class WMShellModule {
            DesktopState desktopState,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            FocusTransitionObserver focusTransitionObserver,
            ShellController shellController) {
            ShellController shellController,
            ShellTaskOrganizer shellTaskOrganizer) {
        return new ShellDesktopStateImpl(desktopState, desktopUserRepositories,
                focusTransitionObserver, shellController);
                focusTransitionObserver, shellController, shellTaskOrganizer);
    }

    @WMSingleton
+3 −4
Original line number Diff line number Diff line
@@ -4095,11 +4095,10 @@ class DesktopTasksController(

        if (DesktopExperienceFlags.ENABLE_DESKTOP_FIRST_TOP_FULLSCREEN_BUGFIX.isTrue) {
            val anyDeskActive = repository.isAnyDeskActive(targetDisplayId)
            // TODO(b/436462692) - Make `getFocusedTaskOnDisplay` always returns the latest TaskInfo
            val focusedTask =
                focusTransitionObserver.getFocusedTaskOnDisplay(targetDisplayId)?.let {
                    shellTaskOrganizer.getRunningTaskInfo(it.taskId)
                }
                shellTaskOrganizer.getRunningTaskInfo(
                    focusTransitionObserver.getFocusedTaskIdOnDisplay(targetDisplayId)
                )
            val isFullscreenFocused = focusedTask?.isFullscreen == true
            val isNonHomeFocused = focusedTask?.activityType != ACTIVITY_TYPE_HOME
            logV(
+6 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.wm.shell.desktopmode

import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.shared.desktopmode.DesktopState
import com.android.wm.shell.sysui.ShellController
import com.android.wm.shell.transition.FocusTransitionObserver
@@ -25,6 +26,7 @@ class ShellDesktopStateImpl(
    private val desktopUserRepositories: DesktopUserRepositories,
    private val focusTransitionObserver: FocusTransitionObserver,
    private val shellController: ShellController,
    private val shellTaskOrganizer: ShellTaskOrganizer,
) : ShellDesktopState, DesktopState by desktopState {
    /** Checks if the given display has an active desktop session (i.e., running freeform tasks). */
    private fun isInDesktop(displayId: Int): Boolean =
@@ -34,7 +36,10 @@ class ShellDesktopStateImpl(

    /** Checks if the currently focused task on the given display is the home screen. */
    private fun isHomeFocused(displayId: Int): Boolean {
        val focusedTask = focusTransitionObserver.getFocusedTaskOnDisplay(displayId)
        val focusedTask =
            shellTaskOrganizer.getRunningTaskInfo(
                focusTransitionObserver.getFocusedTaskIdOnDisplay(displayId)
            )
        if (focusedTask == null) {
            // A null focused task can occur if the Home activity launched before Shell was
            // fully initialized, and this display has not yet received focus. In this case,
+10 −8
Original line number Diff line number Diff line
@@ -269,17 +269,19 @@ public class FocusTransitionObserver {
    }

    /**
     * Gets the focused task on a specific display. Be careful when you access the properties of the
     * returned value which may be stale (b/436462692).
     * Gets the focused task ID on a specific display.
     *
     * @param displayId The ID of the display.
     * @return The {@link RunningTaskInfo} of the focused task on the given display,
     *         or {@code null} if no task is focused or display not recorded in the observer.
     * @return The task ID of the focused task on the given display,
     *         or {@code INVALID_TASK_ID} if no task is focused or display not recorded in the
     *         observer.
     */
    @Nullable
    public RunningTaskInfo getFocusedTaskOnDisplay(int displayId) {
        // TODO(b/436462692) - Make `getFocusedTaskOnDisplay` always returns the latest TaskInfo
        return mFocusedTaskOnDisplay.get(displayId);
    public int getFocusedTaskIdOnDisplay(int displayId) {
        final RunningTaskInfo taskInfo = mFocusedTaskOnDisplay.get(displayId);
        // Some properties of `taskInfo` can be stale as this observer only updates the cache when
        // the focus changes. So we here returns only taskId to ask callers to fetch the TaskInfo
        // if needed.
        return taskInfo != null ? taskInfo.taskId : INVALID_TASK_ID;
    }

    /** Dumps focused display and tasks. */
+4 −4
Original line number Diff line number Diff line
@@ -5865,8 +5865,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
        tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM

        val focusedFullscreenTask = setUpFullscreenTask()
        whenever(focusTransitionObserver.getFocusedTaskOnDisplay(any()))
            .thenReturn(focusedFullscreenTask)
        whenever(focusTransitionObserver.getFocusedTaskIdOnDisplay(any()))
            .thenReturn(focusedFullscreenTask.taskId)

        val fullscreenTask = createFullscreenTask()

@@ -6262,8 +6262,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
        tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM

        val focusedFullscreenTask = setUpFullscreenTask()
        whenever(focusTransitionObserver.getFocusedTaskOnDisplay(any()))
            .thenReturn(focusedFullscreenTask)
        whenever(focusTransitionObserver.getFocusedTaskIdOnDisplay(any()))
            .thenReturn(focusedFullscreenTask.taskId)

        val freeformTask = createFreeformTask(displayId = DEFAULT_DISPLAY)

Loading