summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Eghosa Ewansiha-Vlachavas <eevlachavas@google.com> 2024-03-08 15:09:45 +0000
committer Eghosa Ewansiha-Vlachavas <eevlachavas@google.com> 2024-03-08 18:41:19 +0000
commit2b8b6f23c4cd7af2ef2ab9cd6aed3f8d4067af54 (patch)
treedec37d4392db8fd73a14e0691e0741acaf78ef18
parent6ce00f979e5bd69851967f48371807b6bc2b56e3 (diff)
Replace desktop mode screen size check with config property flag
The screen layout of a device can be modified by the user through setting a higher or lower density, meaning the screen layout size can change from the default value making it an unreliable gate. Calculating the screen size in inches using the window metrics was also explored but did not result in accureate values given current APIs and thus is also an unreliable gate. Instead introduce a new config property flag, to gate the feature, which represents whether a device supports desktop mode. By default this will be false but set to true in the config of supported devices. Bug: 326957646 Fixes: 328684732 Test: atest WMShellUnitTests:DesktopModeWindowDecorViewModelTests Test: atest WMShellUnitTests:DesktopTasksControllerTest Change-Id: I54329693746c6cb44ea4a54a6de00b33f9bc0a9c
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java37
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt31
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt63
6 files changed, 87 insertions, 51 deletions
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index a541c590575f..c68b0be47228 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -148,4 +148,7 @@
<!-- Whether pointer pilfer is required to start back animation. -->
<bool name="config_backAnimationRequiresPointerPilfer">true</bool>
+
+ <!-- Whether desktop mode is supported on the current device -->
+ <bool name="config_isDesktopModeSupported">false</bool>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
index 7b8486870a40..494d89307514 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
@@ -16,13 +16,13 @@
package com.android.wm.shell.desktopmode;
-import static android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE;
-
import android.annotation.NonNull;
-import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
import android.os.SystemProperties;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.window.flags.Flags;
+import com.android.wm.shell.R;
/**
* Constants for desktop mode feature
@@ -70,8 +70,11 @@ public class DesktopModeStatus {
private static final boolean USE_ROUNDED_CORNERS = SystemProperties.getBoolean(
"persist.wm.debug.desktop_use_rounded_corners", true);
- private static final boolean ENFORCE_DISPLAY_RESTRICTIONS = SystemProperties.getBoolean(
- "persist.wm.debug.desktop_mode_enforce_display_restrictions", true);
+ /**
+ * Flag to indicate whether to restrict desktop mode to supported devices.
+ */
+ private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
+ "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
/**
* Return {@code true} if desktop windowing is enabled
@@ -113,19 +116,25 @@ public class DesktopModeStatus {
}
/**
- * Return whether the display size restrictions should be enforced.
+ * Return {@code true} if desktop mode should be restricted to supported devices.
+ */
+ @VisibleForTesting
+ public static boolean enforceDeviceRestrictions() {
+ return ENFORCE_DEVICE_RESTRICTIONS;
+ }
+
+ /**
+ * Return {@code true} if the current device supports desktop mode.
*/
- public static boolean enforceDisplayRestrictions() {
- return ENFORCE_DISPLAY_RESTRICTIONS;
+ @VisibleForTesting
+ public static boolean isDesktopModeSupported(@NonNull Context context) {
+ return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
}
/**
- * Return {@code true} if the display associated with the task is at least of size
- * {@link android.content.res.Configuration#SCREENLAYOUT_SIZE_XLARGE} or has been overridden to
- * ignore the size constraint.
+ * Return {@code true} if desktop mode can be entered on the current device.
*/
- public static boolean meetsMinimumDisplayRequirements(@NonNull RunningTaskInfo taskInfo) {
- return !enforceDisplayRestrictions()
- || taskInfo.configuration.isLayoutSizeAtLeast(SCREENLAYOUT_SIZE_XLARGE);
+ public static boolean canEnterDesktopMode(@NonNull Context context) {
+ return !enforceDeviceRestrictions() || isDesktopModeSupported(context);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 2c66fd681f62..09a87aeccbc6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -305,7 +305,7 @@ class DesktopTasksController(
task: RunningTaskInfo,
wct: WindowContainerTransaction = WindowContainerTransaction()
) {
- if (!DesktopModeStatus.meetsMinimumDisplayRequirements(task)) {
+ if (!DesktopModeStatus.canEnterDesktopMode(context)) {
KtProtoLog.w(
WM_SHELL_DESKTOP_MODE, "DesktopTasksController: Cannot enter desktop, " +
"display does not meet minimum size requirements")
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index dc9b532a70a6..6e6e0102de93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -1058,7 +1058,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED
&& taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
&& !taskInfo.configuration.windowConfiguration.isAlwaysOnTop()
- && DesktopModeStatus.meetsMinimumDisplayRequirements(taskInfo);
+ && DesktopModeStatus.canEnterDesktopMode(mContext);
}
private void createWindowDecoration(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 4c8a3088a79f..17175db30b52 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -23,8 +23,6 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
-import android.content.res.Configuration.SCREENLAYOUT_SIZE_NORMAL
-import android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE
import android.os.Binder
import android.testing.AndroidTestingRunner
import android.view.Display.DEFAULT_DISPLAY
@@ -38,6 +36,7 @@ import android.window.TransitionRequestInfo
import android.window.WindowContainerTransaction
import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.never
import com.android.dx.mockito.inline.extended.StaticMockitoSession
@@ -88,6 +87,7 @@ import org.mockito.Mockito.anyInt
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
+import org.mockito.quality.Strictness
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -125,7 +125,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Before
fun setUp() {
- mockitoSession = mockitoSession().spyStatic(DesktopModeStatus::class.java).startMocking()
+ mockitoSession = mockitoSession().strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java).startMocking()
whenever(DesktopModeStatus.isEnabled()).thenReturn(true)
shellInit = Mockito.spy(ShellInit(testExecutor))
@@ -334,25 +335,25 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun moveToDesktop_screenSizeBelowXLarge_doesNothing() {
+ fun moveToDesktop_deviceNotSupported_doesNothing() {
val task = setUpFullscreenTask()
- // Update screen layout to be below minimum size
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL
+ // Simulate non compatible device
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
controller.moveToDesktop(task)
verifyWCTNotExecuted()
}
@Test
- fun moveToDesktop_screenSizeBelowXLarge_displayRestrictionsOverridden_taskIsMovedToDesktop() {
+ fun moveToDesktop_deviceNotSupported_deviceRestrictionsOverridden_taskIsMovedToDesktop() {
val task = setUpFullscreenTask()
- // Update screen layout to be below minimum size
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL
+ // Simulate non compatible device
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
- // Simulate enforce display restrictions system property overridden to false
- whenever(DesktopModeStatus.enforceDisplayRestrictions()).thenReturn(false)
+ // Simulate enforce device restrictions system property overridden to false
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(false)
controller.moveToDesktop(task)
@@ -362,7 +363,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun moveToDesktop_screenSizeXLarge_taskIsMovedToDesktop() {
+ fun moveToDesktop_deviceSupported_taskIsMovedToDesktop() {
val task = setUpFullscreenTask()
controller.moveToDesktop(task)
@@ -857,7 +858,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
private fun setUpFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
val task = createFullscreenTask(displayId)
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_XLARGE
+ doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
runningTasks.add(task)
return task
@@ -865,7 +867,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
private fun setUpSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
val task = createSplitScreenTask(displayId)
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_XLARGE
+ doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
whenever(splitScreenController.isTaskInSplitScreen(task.taskId)).thenReturn(true)
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
runningTasks.add(task)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 83519bbf624a..6940739d68b2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -23,8 +23,6 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.content.Context
-import android.content.res.Configuration.SCREENLAYOUT_SIZE_NORMAL
-import android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE
import android.graphics.Rect
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
@@ -47,6 +45,7 @@ import android.view.WindowInsets.Type.navigationBars
import android.view.WindowInsets.Type.statusBars
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.window.flags.Flags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -367,30 +366,41 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun testWindowDecor_screenSizeBelowXLarge_decorNotCreated() {
- val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
- // Update screen layout to be below minimum size
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL
+ fun testWindowDecor_desktopModeUnsupportedOnDevice_decorNotCreated() {
+ val mockitoSession: StaticMockitoSession = mockitoSession()
+ .strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java)
+ .startMocking()
+ try {
+ // Simulate default enforce device restrictions system property
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
- onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
+ // Simulate device that doesn't support desktop mode
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+
+ onTaskOpening(task)
+ verify(mockDesktopModeWindowDecorFactory, never())
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ } finally {
+ mockitoSession.finishMocking()
+ }
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun testWindowDecor_screenSizeBelowXLarge_displayRestrictionsOverridden_decorCreated() {
+ fun testWindowDecor_desktopModeUnsupportedOnDevice_deviceRestrictionsOverridden_decorCreated() {
val mockitoSession: StaticMockitoSession = mockitoSession()
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus::class.java)
.startMocking()
try {
- // Simulate enforce display restrictions system property overridden to false
- whenever(DesktopModeStatus.enforceDisplayRestrictions()).thenReturn(false)
+ // Simulate enforce device restrictions system property overridden to false
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(false)
+ // Simulate device that doesn't support desktop mode
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
- // Update screen layout to be below minimum size
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL
setUpMockDecorationsForTasks(task)
onTaskOpening(task)
@@ -403,14 +413,25 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun testWindowDecor_screenSizeXLarge_decorCreated() {
- val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
- task.configuration.screenLayout = SCREENLAYOUT_SIZE_XLARGE
- setUpMockDecorationsForTasks(task)
+ fun testWindowDecor_deviceSupportsDesktopMode_decorCreated() {
+ val mockitoSession: StaticMockitoSession = mockitoSession()
+ .strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java)
+ .startMocking()
+ try {
+ // Simulate default enforce device restrictions system property
+ whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
- onTaskOpening(task)
- verify(mockDesktopModeWindowDecorFactory)
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
+ doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ setUpMockDecorationsForTasks(task)
+
+ onTaskOpening(task)
+ verify(mockDesktopModeWindowDecorFactory)
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ } finally {
+ mockitoSession.finishMocking()
+ }
}
private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {