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
This commit is contained in:
Ats Jenk
2022-09-02 11:06:15 -07:00
parent d2a46ddf38
commit aa39e03993
4 changed files with 82 additions and 34 deletions

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;

View File

@@ -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();