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

Commit 6f289bec authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Exit desktop-immersive when app unrequests immersive" into main

parents f0a123f8 fc279a45
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ public abstract class WMShellModule {
            ShellInit shellInit,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<DesktopRepository> desktopRepository,
            Optional<DesktopTasksController> desktopTasksController,
            LaunchAdjacentController launchAdjacentController,
            WindowDecorViewModel windowDecorViewModel) {
        // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
@@ -364,7 +365,8 @@ public abstract class WMShellModule {
                ? shellInit
                : null;
        return new FreeformTaskListener(context, init, shellTaskOrganizer,
                desktopRepository, launchAdjacentController, windowDecorViewModel);
                desktopRepository, desktopTasksController, launchAdjacentController,
                windowDecorViewModel);
    }

    @WMSingleton
+12 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
import com.android.wm.shell.windowdecor.extension.isFullscreen
import com.android.wm.shell.windowdecor.extension.isMultiWindow
import com.android.wm.shell.windowdecor.extension.requestingImmersive
import java.io.PrintWriter
import java.util.Optional
import java.util.concurrent.Executor
@@ -1844,6 +1845,17 @@ class DesktopTasksController(
        userId = newUserId
    }

    /** Called when a task's info changes. */
    fun onTaskInfoChanged(taskInfo: RunningTaskInfo) {
        if (!Flags.enableFullyImmersiveInDesktop()) return
        val inImmersive = taskRepository.isTaskInFullImmersiveState(taskInfo.taskId)
        val requestingImmersive = taskInfo.requestingImmersive
        if (inImmersive && !requestingImmersive) {
            // Exit immersive if the app is no longer requesting it.
            exitDesktopTaskFromFullImmersive(taskInfo)
        }
    }

    private fun dump(pw: PrintWriter, prefix: String) {
        val innerPrefix = "$prefix  "
        pw.println("${prefix}DesktopTasksController")
+5 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInit;
@@ -50,6 +51,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
    private final Context mContext;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final Optional<DesktopRepository> mDesktopRepository;
    private final Optional<DesktopTasksController> mDesktopTasksController;
    private final WindowDecorViewModel mWindowDecorationViewModel;
    private final LaunchAdjacentController mLaunchAdjacentController;

@@ -65,12 +67,14 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
            ShellInit shellInit,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<DesktopRepository> desktopRepository,
            Optional<DesktopTasksController> desktopTasksController,
            LaunchAdjacentController launchAdjacentController,
            WindowDecorViewModel windowDecorationViewModel) {
        mContext = context;
        mShellTaskOrganizer = shellTaskOrganizer;
        mWindowDecorationViewModel = windowDecorationViewModel;
        mDesktopRepository = desktopRepository;
        mDesktopTasksController = desktopTasksController;
        mLaunchAdjacentController = launchAdjacentController;
        if (shellInit != null) {
            shellInit.addInitCallback(this::onInit, this);
@@ -147,6 +151,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,

        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Info Changed: #%d",
                taskInfo.taskId);
        mDesktopTasksController.ifPresent(c -> c.onTaskInfoChanged(taskInfo));
        mWindowDecorationViewModel.onTaskInfoChanged(taskInfo);
        state.mTaskInfo = taskInfo;
        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
+27 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.view.Display.DEFAULT_DISPLAY
import android.view.DragEvent
import android.view.Gravity
import android.view.SurfaceControl
import android.view.WindowInsets
import android.view.WindowManager
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_CLOSE
@@ -75,6 +76,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
import com.android.window.flags.Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP
import com.android.wm.shell.MockToken
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -142,6 +144,7 @@ import org.mockito.Mockito
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.times
@@ -3151,6 +3154,30 @@ class DesktopTasksControllerTest : ShellTestCase() {
    })
  }

  @Test
  @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
  fun onTaskInfoChanged_inImmersiveUnrequestsImmersive_exits() {
    val task = setUpFreeformTask(DEFAULT_DISPLAY)
    taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, immersive = true)

    task.requestedVisibleTypes = WindowInsets.Type.statusBars()
    controller.onTaskInfoChanged(task)

    verify(mockDesktopFullImmersiveTransitionHandler).exitImmersive(eq(task), any())
  }

  @Test
  @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
  fun onTaskInfoChanged_notInImmersiveUnrequestsImmersive_noReExit() {
    val task = setUpFreeformTask(DEFAULT_DISPLAY)
    taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, immersive = false)

    task.requestedVisibleTypes = WindowInsets.Type.statusBars()
    controller.onTaskInfoChanged(task)

    verify(mockDesktopFullImmersiveTransitionHandler, never()).exitImmersive(eq(task), any())
  }

  /**
   * Assert that an unhandled drag event launches a PendingIntent with the
   * windowing mode and bounds we are expecting.
+16 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
@@ -75,6 +76,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
    @Mock
    private DesktopRepository mDesktopRepository;
    @Mock
    private DesktopTasksController mDesktopTasksController;
    @Mock
    private LaunchAdjacentController mLaunchAdjacentController;
    private FreeformTaskListener mFreeformTaskListener;
    private StaticMockitoSession mMockitoSession;
@@ -90,6 +93,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
                mShellInit,
                mTaskOrganizer,
                Optional.of(mDesktopRepository),
                Optional.of(mDesktopTasksController),
                mLaunchAdjacentController,
                mWindowDecorViewModel);
    }
@@ -177,6 +181,18 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
        verify(mDesktopRepository).removeFreeformTask(task.displayId, task.taskId);
    }

    @Test
    public void onTaskInfoChanged_withDesktopController_forwards() {
        ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder()
                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
        task.isVisible = true;
        mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);

        mFreeformTaskListener.onTaskInfoChanged(task);

        verify(mDesktopTasksController).onTaskInfoChanged(task);
    }

    @After
    public void tearDown() {
        mMockitoSession.finishMocking();