diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java index 9230c22c5d952..ca977ed2cb94c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java @@ -178,6 +178,14 @@ public class RootTaskDisplayAreaOrganizer extends DisplayAreaOrganizer { applyConfigChangesToContext(displayAreaInfo); } + /** + * Returns the {@link DisplayAreaInfo} of the {@link DisplayAreaInfo#displayId}. + */ + @Nullable + public DisplayAreaInfo getDisplayAreaInfo(int displayId) { + return mDisplayAreasInfo.get(displayId); + } + /** * Applies the {@link DisplayAreaInfo} to the {@link DisplayAreaContext} specified by * {@link DisplayAreaInfo#displayId}. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 247ba605ae58e..2285821d1d8ec 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -27,7 +27,6 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.launcher3.icons.IconProvider; -import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.TaskViewTransitions; @@ -598,13 +597,13 @@ public abstract class WMShellModule { static Optional provideDesktopModeController( Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, - RootDisplayAreaOrganizer rootDisplayAreaOrganizer, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread Handler mainHandler, Transitions transitions ) { if (DesktopMode.IS_SUPPORTED) { return Optional.of(new DesktopModeController(context, shellInit, shellTaskOrganizer, - rootDisplayAreaOrganizer, mainHandler, transitions)); + rootTaskDisplayAreaOrganizer, mainHandler, transitions)); } else { return Optional.empty(); } 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 c07ce1065302a..6e44d58cffaea 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 @@ -22,19 +22,21 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; +import android.app.WindowConfiguration; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; +import android.window.DisplayAreaInfo; import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; -import com.android.wm.shell.RootDisplayAreaOrganizer; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; @@ -47,18 +49,18 @@ public class DesktopModeController { private final Context mContext; private final ShellTaskOrganizer mShellTaskOrganizer; - private final RootDisplayAreaOrganizer mRootDisplayAreaOrganizer; + private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final SettingsObserver mSettingsObserver; private final Transitions mTransitions; public DesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, - RootDisplayAreaOrganizer rootDisplayAreaOrganizer, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread Handler mainHandler, Transitions transitions) { mContext = context; mShellTaskOrganizer = shellTaskOrganizer; - mRootDisplayAreaOrganizer = rootDisplayAreaOrganizer; + mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mSettingsObserver = new SettingsObserver(mContext, mainHandler); mTransitions = transitions; shellInit.addInitCallback(this::onInit, this); @@ -92,15 +94,32 @@ public class DesktopModeController { wct.merge(mShellTaskOrganizer.prepareClearBoundsForStandardTasks(displayId), true /* transfer */); } - wct.merge(mRootDisplayAreaOrganizer.prepareWindowingModeChange(displayId, - targetWindowingMode), true /* transfer */); + prepareWindowingModeChange(wct, displayId, targetWindowingMode); if (Transitions.ENABLE_SHELL_TRANSITIONS) { mTransitions.startTransition(TRANSIT_CHANGE, wct, null); } else { - mRootDisplayAreaOrganizer.applyTransaction(wct); + mRootTaskDisplayAreaOrganizer.applyTransaction(wct); } } + private void prepareWindowingModeChange(WindowContainerTransaction wct, + int displayId, @WindowConfiguration.WindowingMode int windowingMode) { + DisplayAreaInfo displayAreaInfo = mRootTaskDisplayAreaOrganizer + .getDisplayAreaInfo(displayId); + if (displayAreaInfo == null) { + ProtoLog.e(WM_SHELL_DESKTOP_MODE, + "unable to update windowing mode for display %d display not found", displayId); + return; + } + + ProtoLog.d(WM_SHELL_DESKTOP_MODE, + "setWindowingMode: displayId=%d current wmMode=%d new wmMode=%d", displayId, + displayAreaInfo.configuration.windowConfiguration.getWindowingMode(), + windowingMode); + + wct.setWindowingMode(displayAreaInfo.token, windowingMode); + } + /** * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE} */ 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 577942505b130..c628f3994d8de 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 @@ -32,13 +32,14 @@ import android.app.WindowConfiguration; import android.os.Handler; import android.os.IBinder; import android.testing.AndroidTestingRunner; +import android.window.DisplayAreaInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction.Change; import androidx.test.filters.SmallTest; -import com.android.wm.shell.RootDisplayAreaOrganizer; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.ShellExecutor; @@ -59,7 +60,7 @@ public class DesktopModeControllerTest extends ShellTestCase { @Mock private ShellTaskOrganizer mShellTaskOrganizer; @Mock - private RootDisplayAreaOrganizer mRootDisplayAreaOrganizer; + private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; @Mock private ShellExecutor mTestExecutor; @Mock @@ -75,7 +76,7 @@ public class DesktopModeControllerTest extends ShellTestCase { mShellInit = Mockito.spy(new ShellInit(mTestExecutor)); mController = new DesktopModeController(mContext, mShellInit, mShellTaskOrganizer, - mRootDisplayAreaOrganizer, mMockHandler, mMockTransitions); + mRootTaskDisplayAreaOrganizer, mMockHandler, mMockTransitions); mShellInit.init(); } @@ -94,19 +95,19 @@ public class DesktopModeControllerTest extends ShellTestCase { when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks( mContext.getDisplayId())).thenReturn(taskWct); - // Create a fake WCT to simulate setting display windowing mode to freeform - WindowContainerTransaction displayWct = new WindowContainerTransaction(); + // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly MockToken displayMockToken = new MockToken(); - displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FREEFORM); - when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(), - WINDOWING_MODE_FREEFORM)).thenReturn(displayWct); + DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken, + mContext.getDisplayId(), 0); + when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId())) + .thenReturn(displayAreaInfo); // The test mController.updateDesktopModeActive(true); ArgumentCaptor arg = ArgumentCaptor.forClass( WindowContainerTransaction.class); - verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture()); + verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture()); // WCT should have 2 changes - clear task wm mode and set display wm mode WindowContainerTransaction wct = arg.getValue(); @@ -118,7 +119,7 @@ public class DesktopModeControllerTest extends ShellTestCase { assertThat(taskWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED); // Verify executed WCT has a change for setting display windowing mode to freeform - Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder()); + Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder()); assertThat(displayWmModeChange).isNotNull(); assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FREEFORM); } @@ -139,19 +140,19 @@ public class DesktopModeControllerTest extends ShellTestCase { when(mShellTaskOrganizer.prepareClearBoundsForStandardTasks( mContext.getDisplayId())).thenReturn(taskBoundsWct); - // Create a fake WCT to simulate setting display windowing mode to fullscreen - WindowContainerTransaction displayWct = new WindowContainerTransaction(); + // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly MockToken displayMockToken = new MockToken(); - displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FULLSCREEN); - when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(), - WINDOWING_MODE_FULLSCREEN)).thenReturn(displayWct); + DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken, + mContext.getDisplayId(), 0); + when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId())) + .thenReturn(displayAreaInfo); // The test mController.updateDesktopModeActive(false); ArgumentCaptor arg = ArgumentCaptor.forClass( WindowContainerTransaction.class); - verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture()); + verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture()); // WCT should have 3 changes - clear task wm mode and bounds and set display wm mode WindowContainerTransaction wct = arg.getValue(); @@ -171,7 +172,7 @@ public class DesktopModeControllerTest extends ShellTestCase { .isTrue(); // Verify executed WCT has a change for setting display windowing mode to fullscreen - Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder()); + Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder()); assertThat(displayWmModeChange).isNotNull(); assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FULLSCREEN); }