From aa39e0399369331738582b38c6da7c11abb627cd Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Fri, 2 Sep 2022 11:06:15 -0700 Subject: [PATCH] Only clear bounds and windowing mode for standard When we switch between desktop and focused modes, we clear bounds and reset windowing mode for all tasks. Make sure this affects only tasks that have activity type set to ACTIVITY_TYPE_STANDARD. This ensures we don't clear bounds or reset windowing mode for launcher or split screen stages etc. Bug: 244348395 Test: atest ShellTaskOrganizerTests Change-Id: Iaf84cb2733a6ffa93c267cb8c716e7c0eb7ca13f --- .../android/wm/shell/ShellTaskOrganizer.java | 17 +++- .../desktopmode/DesktopModeController.java | 5 +- .../wm/shell/ShellTaskOrganizerTests.java | 82 ++++++++++++++----- .../DesktopModeControllerTest.java | 12 +-- 4 files changed, 82 insertions(+), 34 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index d5d4935f0529b..b5409b7d78afe 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -16,6 +16,7 @@ package com.android.wm.shell; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; @@ -695,15 +696,19 @@ public class ShellTaskOrganizer extends TaskOrganizer implements /** * Create a {@link WindowContainerTransaction} to clear task bounds. * + * Only affects tasks that have {@link RunningTaskInfo#getActivityType()} set to + * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}. + * * @param displayId display id for tasks that will have bounds cleared * @return {@link WindowContainerTransaction} with pending operations to clear bounds */ - public WindowContainerTransaction prepareClearBoundsForTasks(int displayId) { + public WindowContainerTransaction prepareClearBoundsForStandardTasks(int displayId) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "prepareClearBoundsForTasks: displayId=%d", displayId); WindowContainerTransaction wct = new WindowContainerTransaction(); for (int i = 0; i < mTasks.size(); i++) { RunningTaskInfo taskInfo = mTasks.valueAt(i).getTaskInfo(); - if (taskInfo.displayId == displayId) { + if ((taskInfo.displayId == displayId) && (taskInfo.getActivityType() + == WindowConfiguration.ACTIVITY_TYPE_STANDARD)) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "clearing bounds for token=%s taskInfo=%s", taskInfo.token, taskInfo); wct.setBounds(taskInfo.token, null); @@ -715,17 +720,21 @@ public class ShellTaskOrganizer extends TaskOrganizer implements /** * Create a {@link WindowContainerTransaction} to clear task level freeform setting. * + * Only affects tasks that have {@link RunningTaskInfo#getActivityType()} set to + * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}. + * * @param displayId display id for tasks that will have windowing mode reset to {@link * WindowConfiguration#WINDOWING_MODE_UNDEFINED} * @return {@link WindowContainerTransaction} with pending operations to clear windowing mode */ - public WindowContainerTransaction prepareClearFreeformForTasks(int displayId) { + public WindowContainerTransaction prepareClearFreeformForStandardTasks(int displayId) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "prepareClearFreeformForTasks: displayId=%d", displayId); WindowContainerTransaction wct = new WindowContainerTransaction(); for (int i = 0; i < mTasks.size(); i++) { RunningTaskInfo taskInfo = mTasks.valueAt(i).getTaskInfo(); if (taskInfo.displayId == displayId - && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { + && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM + && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "clearing windowing mode for token=%s taskInfo=%s", taskInfo.token, taskInfo); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java index 5849e163f0e2f..595455e7d575d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java @@ -73,14 +73,15 @@ public class DesktopModeController { WindowContainerTransaction wct = new WindowContainerTransaction(); // Reset freeform windowing mode that is set per task level (tasks should inherit // container value) - wct.merge(mShellTaskOrganizer.prepareClearFreeformForTasks(displayId), true /* transfer */); + wct.merge(mShellTaskOrganizer.prepareClearFreeformForStandardTasks(displayId), + true /* transfer */); int targetWindowingMode; if (enabled) { targetWindowingMode = WINDOWING_MODE_FREEFORM; } else { targetWindowingMode = WINDOWING_MODE_FULLSCREEN; // Clear any resized bounds - wct.merge(mShellTaskOrganizer.prepareClearBoundsForTasks(displayId), + wct.merge(mShellTaskOrganizer.prepareClearBoundsForStandardTasks(displayId), true /* transfer */); } wct.merge(mRootDisplayAreaOrganizer.prepareWindowingModeChange(displayId, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java index b29c436d0d51a..7cbace5af48f7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java @@ -16,6 +16,8 @@ package com.android.wm.shell; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; @@ -637,26 +639,22 @@ public class ShellTaskOrganizerTests extends ShellTestCase { } @Test - public void testPrepareClearBoundsForTasks() { - RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_UNDEFINED); - task1.displayId = 1; + public void testPrepareClearBoundsForStandardTasks() { MockToken token1 = new MockToken(); - task1.token = token1.token(); + RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_UNDEFINED, token1); mOrganizer.onTaskAppeared(task1, null); - RunningTaskInfo task2 = createTaskInfo(2, WINDOWING_MODE_UNDEFINED); - task2.displayId = 1; MockToken token2 = new MockToken(); - task2.token = token2.token(); + RunningTaskInfo task2 = createTaskInfo(2, WINDOWING_MODE_UNDEFINED, token2); mOrganizer.onTaskAppeared(task2, null); - RunningTaskInfo otherDisplayTask = createTaskInfo(3, WINDOWING_MODE_UNDEFINED); - otherDisplayTask.displayId = 2; MockToken otherDisplayToken = new MockToken(); - otherDisplayTask.token = otherDisplayToken.token(); + RunningTaskInfo otherDisplayTask = createTaskInfo(3, WINDOWING_MODE_UNDEFINED, + otherDisplayToken); + otherDisplayTask.displayId = 2; mOrganizer.onTaskAppeared(otherDisplayTask, null); - WindowContainerTransaction wct = mOrganizer.prepareClearBoundsForTasks(1); + WindowContainerTransaction wct = mOrganizer.prepareClearBoundsForStandardTasks(1); assertEquals(wct.getChanges().size(), 2); Change boundsChange1 = wct.getChanges().get(token1.binder()); @@ -673,26 +671,40 @@ public class ShellTaskOrganizerTests extends ShellTestCase { } @Test - public void testPrepareClearFreeformForTasks() { - RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_FREEFORM); - task1.displayId = 1; + public void testPrepareClearBoundsForStandardTasks_onlyClearActivityTypeStandard() { MockToken token1 = new MockToken(); - task1.token = token1.token(); + RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_UNDEFINED, token1); mOrganizer.onTaskAppeared(task1, null); - RunningTaskInfo task2 = createTaskInfo(2, WINDOWING_MODE_MULTI_WINDOW); - task2.displayId = 1; MockToken token2 = new MockToken(); - task2.token = token2.token(); + RunningTaskInfo task2 = createTaskInfo(2, WINDOWING_MODE_UNDEFINED, token2); + task2.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_HOME); + mOrganizer.onTaskAppeared(task2, null); + + WindowContainerTransaction wct = mOrganizer.prepareClearBoundsForStandardTasks(1); + + // Only clear bounds for task1 + assertEquals(1, wct.getChanges().size()); + assertNotNull(wct.getChanges().get(token1.binder())); + } + + @Test + public void testPrepareClearFreeformForStandardTasks() { + MockToken token1 = new MockToken(); + RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_FREEFORM, token1); + mOrganizer.onTaskAppeared(task1, null); + + MockToken token2 = new MockToken(); + RunningTaskInfo task2 = createTaskInfo(2, WINDOWING_MODE_MULTI_WINDOW, token2); mOrganizer.onTaskAppeared(task2, null); - RunningTaskInfo otherDisplayTask = createTaskInfo(3, WINDOWING_MODE_FREEFORM); - otherDisplayTask.displayId = 2; MockToken otherDisplayToken = new MockToken(); - otherDisplayTask.token = otherDisplayToken.token(); + RunningTaskInfo otherDisplayTask = createTaskInfo(3, WINDOWING_MODE_FREEFORM, + otherDisplayToken); + otherDisplayTask.displayId = 2; mOrganizer.onTaskAppeared(otherDisplayTask, null); - WindowContainerTransaction wct = mOrganizer.prepareClearFreeformForTasks(1); + WindowContainerTransaction wct = mOrganizer.prepareClearFreeformForStandardTasks(1); // Only task with freeform windowing mode and the right display should be updated assertEquals(wct.getChanges().size(), 1); @@ -701,6 +713,24 @@ public class ShellTaskOrganizerTests extends ShellTestCase { assertEquals(wmModeChange1.getWindowingMode(), WINDOWING_MODE_UNDEFINED); } + @Test + public void testPrepareClearFreeformForStandardTasks_onlyClearActivityTypeStandard() { + MockToken token1 = new MockToken(); + RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_FREEFORM, token1); + mOrganizer.onTaskAppeared(task1, null); + + MockToken token2 = new MockToken(); + RunningTaskInfo task2 = createTaskInfo(2, WINDOWING_MODE_FREEFORM, token2); + task2.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_HOME); + mOrganizer.onTaskAppeared(task2, null); + + WindowContainerTransaction wct = mOrganizer.prepareClearFreeformForStandardTasks(1); + + // Only clear freeform for task1 + assertEquals(1, wct.getChanges().size()); + assertNotNull(wct.getChanges().get(token1.binder())); + } + private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) { RunningTaskInfo taskInfo = new RunningTaskInfo(); taskInfo.taskId = taskId; @@ -708,6 +738,14 @@ public class ShellTaskOrganizerTests extends ShellTestCase { return taskInfo; } + private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode, MockToken token) { + RunningTaskInfo taskInfo = createTaskInfo(taskId, windowingMode); + taskInfo.displayId = 1; + taskInfo.token = token.token(); + taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD); + return taskInfo; + } + private static class MockToken { private final WindowContainerToken mToken; private final IBinder mBinder; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java index 58f20da349437..2ef0e7000dd62 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java @@ -88,8 +88,8 @@ public class DesktopModeControllerTest extends ShellTestCase { WindowContainerTransaction taskWct = new WindowContainerTransaction(); MockToken taskMockToken = new MockToken(); taskWct.setWindowingMode(taskMockToken.token(), WINDOWING_MODE_UNDEFINED); - when(mShellTaskOrganizer.prepareClearFreeformForTasks(mContext.getDisplayId())).thenReturn( - taskWct); + when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks( + mContext.getDisplayId())).thenReturn(taskWct); // Create a fake WCT to simulate setting display windowing mode to freeform WindowContainerTransaction displayWct = new WindowContainerTransaction(); @@ -126,15 +126,15 @@ public class DesktopModeControllerTest extends ShellTestCase { WindowContainerTransaction taskWmWct = new WindowContainerTransaction(); MockToken taskWmMockToken = new MockToken(); taskWmWct.setWindowingMode(taskWmMockToken.token(), WINDOWING_MODE_UNDEFINED); - when(mShellTaskOrganizer.prepareClearFreeformForTasks(mContext.getDisplayId())).thenReturn( - taskWmWct); + when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks( + mContext.getDisplayId())).thenReturn(taskWmWct); // Create a fake WCT to simulate clearing task bounds WindowContainerTransaction taskBoundsWct = new WindowContainerTransaction(); MockToken taskBoundsMockToken = new MockToken(); taskBoundsWct.setBounds(taskBoundsMockToken.token(), null); - when(mShellTaskOrganizer.prepareClearBoundsForTasks(mContext.getDisplayId())).thenReturn( - taskBoundsWct); + when(mShellTaskOrganizer.prepareClearBoundsForStandardTasks( + mContext.getDisplayId())).thenReturn(taskBoundsWct); // Create a fake WCT to simulate setting display windowing mode to fullscreen WindowContainerTransaction displayWct = new WindowContainerTransaction();