Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +6 −4 Original line number Diff line number Diff line Loading @@ -885,8 +885,9 @@ class DesktopTasksController( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo ) { val displayWindowingMode = taskInfo.configuration.windowConfiguration.displayWindowingMode val targetWindowingMode = if (displayWindowingMode == WINDOWING_MODE_FREEFORM) { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) { // Display windowing is freeform, set to undefined and inherit it WINDOWING_MODE_UNDEFINED } else { Loading @@ -903,8 +904,9 @@ class DesktopTasksController( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo ) { val displayWindowingMode = taskInfo.configuration.windowConfiguration.displayWindowingMode val targetWindowingMode = if (displayWindowingMode == WINDOWING_MODE_FULLSCREEN) { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FULLSCREEN) { // Display windowing is fullscreen, set to undefined and inherit it WINDOWING_MODE_UNDEFINED } else { Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +45 −4 Original line number Diff line number Diff line Loading @@ -19,14 +19,19 @@ package com.android.wm.shell.windowdecor; 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.content.pm.PackageManager.FEATURE_PC; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; import static android.view.WindowManager.TRANSIT_CHANGE; import android.app.ActivityManager.RunningTaskInfo; import android.content.ContentResolver; import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.provider.Settings; import android.util.SparseArray; import android.view.Choreographer; import android.view.Display; import android.view.MotionEvent; import android.view.SurfaceControl; import android.view.View; Loading Loading @@ -163,10 +168,33 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { } private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) { return taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM || (taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD && taskInfo.configuration.windowConfiguration.getDisplayWindowingMode() == WINDOWING_MODE_FREEFORM); if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { return true; } if (taskInfo.getActivityType() != ACTIVITY_TYPE_STANDARD) { return false; } final DisplayAreaInfo rootDisplayAreaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId); if (rootDisplayAreaInfo != null) { return rootDisplayAreaInfo.configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM; } // It is possible that the rootDisplayAreaInfo is null when a task appears soon enough after // a new display shows up, because TDA may appear after task appears in WM shell. Instead of // fixing the synchronization issues, let's use other signals to "guess" the answer. It is // OK in this context because no other captions other than the legacy developer option // freeform and Kingyo/CF PC may use this class. WM shell should have full control over the // condition where captions should show up in all new cases such as desktop mode, for which // we should use different window decor view models. Ultimately Kingyo/CF PC may need to // spin up their own window decor view model when they start to care about multiple // displays. if (isPc()) { return true; } return taskInfo.displayId != Display.DEFAULT_DISPLAY && forcesDesktopModeOnExternalDisplays(); } private void createWindowDecoration( Loading Loading @@ -313,4 +341,17 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { return true; } } /** * Returns if this device is a PC. */ private boolean isPc() { return mContext.getPackageManager().hasSystemFeature(FEATURE_PC); } private boolean forcesDesktopModeOnExternalDisplays() { final ContentResolver resolver = mContext.getContentResolver(); return Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0; } } No newline at end of file libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +21 −13 Original line number Diff line number Diff line Loading @@ -161,6 +161,10 @@ class DesktopTasksControllerTest : ShellTestCase() { (i.arguments.first() as Rect).set(STABLE_BOUNDS) } val tda = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda) controller = createController() controller.setSplitScreenController(splitScreenController) Loading Loading @@ -336,9 +340,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToDesktop_displayFullscreen_windowingModeSetToFreeform() { fun moveToDesktop_tdaFullscreen_windowingModeSetToFreeform() { val task = setUpFullscreenTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FULLSCREEN val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN controller.moveToDesktop(task) val wct = getLatestMoveToDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading @@ -346,9 +351,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToDesktop_displayFreeform_windowingModeSetToUndefined() { fun moveToDesktop_tdaFreeform_windowingModeSetToUndefined() { val task = setUpFullscreenTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FREEFORM val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM controller.moveToDesktop(task) val wct = getLatestMoveToDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading Loading @@ -481,9 +487,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToFullscreen_displayFullscreen_windowingModeSetToUndefined() { fun moveToFullscreen_tdaFullscreen_windowingModeSetToUndefined() { val task = setUpFreeformTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FULLSCREEN val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN controller.moveToFullscreen(task.taskId) val wct = getLatestExitDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading @@ -491,9 +498,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToFullscreen_displayFreeform_windowingModeSetToFullscreen() { fun moveToFullscreen_tdaFreeform_windowingModeSetToFullscreen() { val task = setUpFreeformTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FREEFORM val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM controller.moveToFullscreen(task.taskId) val wct = getLatestExitDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading Loading @@ -684,7 +692,7 @@ class DesktopTasksControllerTest : ShellTestCase() { createTransition(freeformTask2, type = TRANSIT_TO_FRONT) ) assertThat(result?.changes?.get(freeformTask2.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading @@ -694,7 +702,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val task = createFreeformTask() val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading @@ -706,7 +714,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay)) assertThat(result?.changes?.get(taskDefaultDisplay.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading Loading @@ -792,7 +800,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading Loading @@ -895,7 +903,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val wct = getLatestExitDesktopWct() assertThat(wct.changes[task2.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +6 −4 Original line number Diff line number Diff line Loading @@ -885,8 +885,9 @@ class DesktopTasksController( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo ) { val displayWindowingMode = taskInfo.configuration.windowConfiguration.displayWindowingMode val targetWindowingMode = if (displayWindowingMode == WINDOWING_MODE_FREEFORM) { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) { // Display windowing is freeform, set to undefined and inherit it WINDOWING_MODE_UNDEFINED } else { Loading @@ -903,8 +904,9 @@ class DesktopTasksController( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo ) { val displayWindowingMode = taskInfo.configuration.windowConfiguration.displayWindowingMode val targetWindowingMode = if (displayWindowingMode == WINDOWING_MODE_FULLSCREEN) { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FULLSCREEN) { // Display windowing is fullscreen, set to undefined and inherit it WINDOWING_MODE_UNDEFINED } else { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +45 −4 Original line number Diff line number Diff line Loading @@ -19,14 +19,19 @@ package com.android.wm.shell.windowdecor; 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.content.pm.PackageManager.FEATURE_PC; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; import static android.view.WindowManager.TRANSIT_CHANGE; import android.app.ActivityManager.RunningTaskInfo; import android.content.ContentResolver; import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.provider.Settings; import android.util.SparseArray; import android.view.Choreographer; import android.view.Display; import android.view.MotionEvent; import android.view.SurfaceControl; import android.view.View; Loading Loading @@ -163,10 +168,33 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { } private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) { return taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM || (taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD && taskInfo.configuration.windowConfiguration.getDisplayWindowingMode() == WINDOWING_MODE_FREEFORM); if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { return true; } if (taskInfo.getActivityType() != ACTIVITY_TYPE_STANDARD) { return false; } final DisplayAreaInfo rootDisplayAreaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId); if (rootDisplayAreaInfo != null) { return rootDisplayAreaInfo.configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM; } // It is possible that the rootDisplayAreaInfo is null when a task appears soon enough after // a new display shows up, because TDA may appear after task appears in WM shell. Instead of // fixing the synchronization issues, let's use other signals to "guess" the answer. It is // OK in this context because no other captions other than the legacy developer option // freeform and Kingyo/CF PC may use this class. WM shell should have full control over the // condition where captions should show up in all new cases such as desktop mode, for which // we should use different window decor view models. Ultimately Kingyo/CF PC may need to // spin up their own window decor view model when they start to care about multiple // displays. if (isPc()) { return true; } return taskInfo.displayId != Display.DEFAULT_DISPLAY && forcesDesktopModeOnExternalDisplays(); } private void createWindowDecoration( Loading Loading @@ -313,4 +341,17 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { return true; } } /** * Returns if this device is a PC. */ private boolean isPc() { return mContext.getPackageManager().hasSystemFeature(FEATURE_PC); } private boolean forcesDesktopModeOnExternalDisplays() { final ContentResolver resolver = mContext.getContentResolver(); return Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0; } } No newline at end of file
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +21 −13 Original line number Diff line number Diff line Loading @@ -161,6 +161,10 @@ class DesktopTasksControllerTest : ShellTestCase() { (i.arguments.first() as Rect).set(STABLE_BOUNDS) } val tda = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda) controller = createController() controller.setSplitScreenController(splitScreenController) Loading Loading @@ -336,9 +340,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToDesktop_displayFullscreen_windowingModeSetToFreeform() { fun moveToDesktop_tdaFullscreen_windowingModeSetToFreeform() { val task = setUpFullscreenTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FULLSCREEN val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN controller.moveToDesktop(task) val wct = getLatestMoveToDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading @@ -346,9 +351,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToDesktop_displayFreeform_windowingModeSetToUndefined() { fun moveToDesktop_tdaFreeform_windowingModeSetToUndefined() { val task = setUpFullscreenTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FREEFORM val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM controller.moveToDesktop(task) val wct = getLatestMoveToDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading Loading @@ -481,9 +487,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToFullscreen_displayFullscreen_windowingModeSetToUndefined() { fun moveToFullscreen_tdaFullscreen_windowingModeSetToUndefined() { val task = setUpFreeformTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FULLSCREEN val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN controller.moveToFullscreen(task.taskId) val wct = getLatestExitDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading @@ -491,9 +498,10 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test fun moveToFullscreen_displayFreeform_windowingModeSetToFullscreen() { fun moveToFullscreen_tdaFreeform_windowingModeSetToFullscreen() { val task = setUpFreeformTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FREEFORM val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!! tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM controller.moveToFullscreen(task.taskId) val wct = getLatestExitDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) Loading Loading @@ -684,7 +692,7 @@ class DesktopTasksControllerTest : ShellTestCase() { createTransition(freeformTask2, type = TRANSIT_TO_FRONT) ) assertThat(result?.changes?.get(freeformTask2.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading @@ -694,7 +702,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val task = createFreeformTask() val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading @@ -706,7 +714,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay)) assertThat(result?.changes?.get(taskDefaultDisplay.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading Loading @@ -792,7 +800,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading Loading @@ -895,7 +903,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val wct = getLatestExitDesktopWct() assertThat(wct.changes[task2.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN } @Test Loading