summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Pierre Barbier de Reuille <pbdr@google.com> 2025-01-24 23:16:49 +0000
committer Pierre Barbier de Reuille <pbdr@google.com> 2025-01-29 15:28:13 +0000
commita91be2535be774eaf4b88c5042a657d9a54a38c5 (patch)
tree71b01d331cac4da3f4ba1ed82dfd046947231be5
parentcd66718eb40fca528f857812e3e8afe05caaf3dd (diff)
Add flag to enable desktop mode on specific devices
Flag: com.android.window.flags.enable_desktop_mode_through_dev_option Bug: 382238347 Test: Build and check Change-Id: I054b55c5de295b186fbfd6e29fc7c3a8943d6793
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig10
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt99
-rw-r--r--services/core/java/com/android/server/wm/DesktopModeHelper.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java46
5 files changed, 129 insertions, 50 deletions
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 51d488fdd76b..d20b06738f8c 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -600,3 +600,13 @@ flag {
description: "Enables split screen on non default displays"
bug: "384999213"
}
+
+flag {
+ name: "enable_desktop_mode_through_dev_option"
+ namespace: "lse_desktop_experience"
+ description: "Enables support for desktop mode through developer options for devices eligible for desktop mode."
+ bug: "382238347"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
index 94e0b38ebbf7..e196880aad0f 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -78,17 +78,10 @@ public class DesktopModeStatus {
"persist.wm.debug.desktop_use_rounded_corners", true);
/**
- * Name of the system property used to set the device restriction.
- */
- @VisibleForTesting
- static final String ENFORCE_DEVICE_RESTRICTIONS_PROPERTY =
- "persist.wm.debug.desktop_mode_enforce_device_restrictions";
-
- /**
* Flag to indicate whether to restrict desktop mode to supported devices.
*/
private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
- ENFORCE_DEVICE_RESTRICTIONS_PROPERTY, true);
+ "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
private static final boolean USE_APP_TO_WEB_BUILD_TIME_GENERIC_LINKS =
SystemProperties.getBoolean(
@@ -261,6 +254,7 @@ public class DesktopModeStatus {
return DesktopModeFlags.isDesktopModeForcedEnabled()
&& canShowDesktopModeDevOption(context);
}
+
/**
* Returns whether the multiple desktops feature is enabled for this device (both backend and
* frontend implementations).
@@ -321,7 +315,7 @@ public class DesktopModeStatus {
*/
public static boolean isDeviceEligibleForDesktopMode(@NonNull Context context) {
return !enforceDeviceRestrictions() || isDesktopModeSupported(context) || (
- Flags.forceEnableDesktopModeWithDevOption() && isDesktopModeDevOptionSupported(
+ Flags.enableDesktopModeThroughDevOption() && isDesktopModeDevOptionSupported(
context));
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
index c7466f6d3076..4dac99b14aaf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
@@ -18,7 +18,6 @@ package com.android.wm.shell.shared.desktopmode
import android.content.Context
import android.content.res.Resources
-import android.os.SystemProperties
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.Presubmit
@@ -28,7 +27,6 @@ import android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATUR
import android.window.DesktopModeFlags
import androidx.test.filters.SmallTest
import com.android.internal.R
-import com.android.modules.utils.testing.ExtendedMockitoRule
import com.android.window.flags.Flags
import com.android.wm.shell.ShellTestCase
import com.google.common.truth.Truth.assertThat
@@ -36,8 +34,6 @@ import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -47,14 +43,8 @@ import org.mockito.kotlin.whenever
@Presubmit
@EnableFlags(Flags.FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
class DesktopModeStatusTest : ShellTestCase() {
- @get:Rule(order = 0)
- val mSetFlagsRule = SetFlagsRule();
-
- @get:Rule(order = 1)
- val extendedMockitoRule =
- ExtendedMockitoRule.Builder(this)
- .mockStatic(SystemProperties::class.java)
- .build()
+ @get:Rule
+ val mSetFlagsRule = SetFlagsRule()
private val mockContext = mock<Context>()
private val mockResources = mock<Resources>()
@@ -65,7 +55,7 @@ class DesktopModeStatusTest : ShellTestCase() {
doReturn(false).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported))
doReturn(false).whenever(mockResources).getBoolean(
eq(R.bool.config_isDesktopModeDevOptionSupported)
- );
+ )
doReturn(context.contentResolver).whenever(mockContext).contentResolver
resetDesktopModeFlagsCache()
resetEnforceDeviceRestriction()
@@ -76,28 +66,37 @@ class DesktopModeStatusTest : ShellTestCase() {
fun tearDown() {
resetDesktopModeFlagsCache()
resetEnforceDeviceRestriction()
- resetFlagOverride();
+ resetFlagOverride()
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
+ )
@Test
fun canEnterDesktopMode_DWFlagDisabled_configsOff_returnsFalse() {
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
+ )
@Test
fun canEnterDesktopMode_DWFlagDisabled_configsOn_disableDeviceRestrictions_returnsFalse() {
doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported))
doReturn(true).whenever(mockResources).getBoolean(
eq(R.bool.config_isDesktopModeDevOptionSupported)
- );
+ )
disableEnforceDeviceRestriction()
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
+ )
@Test
fun canEnterDesktopMode_DWFlagDisabled_configDevOptionOn_returnsFalse() {
doReturn(true).whenever(mockResources).getBoolean(
@@ -107,23 +106,28 @@ class DesktopModeStatusTest : ShellTestCase() {
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
+ )
@Test
fun canEnterDesktopMode_DWFlagDisabled_configDevOptionOn_flagOverrideOn_returnsTrue() {
doReturn(true).whenever(mockResources).getBoolean(
eq(R.bool.config_isDesktopModeDevOptionSupported)
)
- setFlagOverride(DesktopModeFlags.ToggleOverride.OVERRIDE_ON);
+ setFlagOverride(DesktopModeFlags.ToggleOverride.OVERRIDE_ON)
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
fun canEnterDesktopMode_DWFlagEnabled_configsOff_returnsFalse() {
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
fun canEnterDesktopMode_DWFlagEnabled_configDesktopModeOff_returnsFalse() {
@@ -134,6 +138,7 @@ class DesktopModeStatusTest : ShellTestCase() {
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
fun canEnterDesktopMode_DWFlagEnabled_configDesktopModeOn_returnsTrue() {
@@ -142,14 +147,16 @@ class DesktopModeStatusTest : ShellTestCase() {
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
fun canEnterDesktopMode_DWFlagEnabled_configsOff_disableDeviceRestrictions_returnsTrue() {
- disableEnforceDeviceRestriction();
+ disableEnforceDeviceRestriction()
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
fun canEnterDesktopMode_DWFlagEnabled_configDevOptionOn_flagOverrideOn_returnsTrue() {
@@ -161,22 +168,48 @@ class DesktopModeStatusTest : ShellTestCase() {
assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
}
- private fun resetEnforceDeviceRestriction() {
- doAnswer { invocation -> invocation.getArgument<Boolean>(1) }.whenever(
- SystemProperties.getBoolean(
- DesktopModeStatus.ENFORCE_DEVICE_RESTRICTIONS_PROPERTY,
- anyBoolean()
- )
+ @Test
+ fun isDeviceEligibleForDesktopMode_configDEModeOn_returnsTrue() {
+ doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported))
+
+ assertThat(DesktopModeStatus.isDeviceEligibleForDesktopMode(mockContext)).isTrue()
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
+ @Test
+ fun isDeviceEligibleForDesktopMode_supportFlagOff_returnsFalse() {
+ assertThat(DesktopModeStatus.isDeviceEligibleForDesktopMode(mockContext)).isFalse()
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
+ @Test
+ fun isDeviceEligibleForDesktopMode_supportFlagOn_returnsFalse() {
+ assertThat(DesktopModeStatus.isDeviceEligibleForDesktopMode(mockContext)).isFalse()
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
+ @Test
+ fun isDeviceEligibleForDesktopMode_supportFlagOn_configDevOptModeOn_returnsTrue() {
+ doReturn(true).whenever(mockResources).getBoolean(
+ eq(R.bool.config_isDesktopModeDevOptionSupported)
)
+
+ assertThat(DesktopModeStatus.isDeviceEligibleForDesktopMode(mockContext)).isTrue()
+ }
+
+ private fun resetEnforceDeviceRestriction() {
+ setEnforceDeviceRestriction(true)
}
private fun disableEnforceDeviceRestriction() {
- doReturn(false).whenever(
- SystemProperties.getBoolean(
- DesktopModeStatus.ENFORCE_DEVICE_RESTRICTIONS_PROPERTY,
- anyBoolean()
- )
- )
+ setEnforceDeviceRestriction(false)
+ }
+
+ private fun setEnforceDeviceRestriction(value: Boolean) {
+ val field = DesktopModeStatus::class.java.getDeclaredField("ENFORCE_DEVICE_RESTRICTIONS")
+ field.isAccessible = true
+ field.setBoolean(null, value)
}
private fun resetDesktopModeFlagsCache() {
diff --git a/services/core/java/com/android/server/wm/DesktopModeHelper.java b/services/core/java/com/android/server/wm/DesktopModeHelper.java
index 7cf685074e56..e3906f9119c2 100644
--- a/services/core/java/com/android/server/wm/DesktopModeHelper.java
+++ b/services/core/java/com/android/server/wm/DesktopModeHelper.java
@@ -23,6 +23,7 @@ import android.window.DesktopModeFlags;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
/**
* Constants for desktop mode feature
@@ -64,12 +65,15 @@ public final class DesktopModeHelper {
* Check if Desktop mode should be enabled because the dev option is shown and enabled.
*/
private static boolean isDesktopModeEnabledByDevOption(@NonNull Context context) {
- return DesktopModeFlags.isDesktopModeForcedEnabled()
- && isDesktopModeDevOptionsSupported(context);
+ return DesktopModeFlags.isDesktopModeForcedEnabled() && (isDesktopModeDevOptionsSupported(
+ context) || isDeviceEligibleForDesktopMode(context));
}
- private static boolean isDeviceEligibleForDesktopMode(@NonNull Context context) {
- return !shouldEnforceDeviceRestrictions() || isDesktopModeSupported(context);
+ @VisibleForTesting
+ static boolean isDeviceEligibleForDesktopMode(@NonNull Context context) {
+ return !shouldEnforceDeviceRestrictions() || isDesktopModeSupported(context) || (
+ Flags.enableDesktopModeThroughDevOption() && isDesktopModeDevOptionsSupported(
+ context));
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java
index 3190cbccf1af..e0b700a4ffe3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeHelperTest.java
@@ -84,13 +84,15 @@ public class DesktopModeHelperTest {
resetFlagOverride();
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION})
@Test
public void canEnterDesktopMode_DWFlagDisabled_configsOff_returnsFalse() {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isFalse();
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION})
@Test
public void canEnterDesktopMode_DWFlagDisabled_configsOn_disableDeviceCheck_returnsFalse()
throws Exception {
@@ -102,7 +104,8 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isFalse();
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION})
@Test
public void canEnterDesktopMode_DWFlagDisabled_configDevOptionOn_returnsFalse() {
doReturn(true).when(mMockResources).getBoolean(
@@ -111,7 +114,8 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isFalse();
}
- @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @DisableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+ Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION})
@Test
public void canEnterDesktopMode_DWFlagDisabled_configDevOptionOn_flagOverrideOn_returnsTrue()
throws Exception {
@@ -122,12 +126,14 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isTrue();
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
public void canEnterDesktopMode_DWFlagEnabled_configsOff_returnsFalse() {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isFalse();
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
public void canEnterDesktopMode_DWFlagEnabled_configDesktopModeOff_returnsFalse() {
@@ -137,6 +143,7 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isFalse();
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
public void canEnterDesktopMode_DWFlagEnabled_configDesktopModeOn_returnsTrue() {
@@ -145,6 +152,7 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isTrue();
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
public void canEnterDesktopMode_DWFlagEnabled_configsOff_disableDeviceRestrictions_returnsTrue()
@@ -154,6 +162,7 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isTrue();
}
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
@Test
public void canEnterDesktopMode_DWFlagEnabled_configDevOptionOn_flagOverrideOn_returnsTrue() {
@@ -165,6 +174,35 @@ public class DesktopModeHelperTest {
assertThat(DesktopModeHelper.canEnterDesktopMode(mMockContext)).isTrue();
}
+ @Test
+ public void isDeviceEligibleForDesktopMode_configDEModeOn_returnsTrue() {
+ doReturn(true).when(mMockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported));
+
+ assertThat(DesktopModeHelper.isDeviceEligibleForDesktopMode(mMockContext)).isTrue();
+ }
+
+ @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
+ @Test
+ public void isDeviceEligibleForDesktopMode_supportFlagOff_returnsFalse() {
+ assertThat(DesktopModeHelper.isDeviceEligibleForDesktopMode(mMockContext)).isFalse();
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
+ @Test
+ public void isDeviceEligibleForDesktopMode_supportFlagOn_returnsFalse() {
+ assertThat(DesktopModeHelper.isDeviceEligibleForDesktopMode(mMockContext)).isFalse();
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
+ @Test
+ public void isDeviceEligibleForDesktopMode_supportFlagOn_configDevOptModeOn_returnsTrue() {
+ doReturn(true).when(mMockResources).getBoolean(
+ eq(R.bool.config_isDesktopModeDevOptionSupported)
+ );
+
+ assertThat(DesktopModeHelper.isDeviceEligibleForDesktopMode(mMockContext)).isTrue();
+ }
+
private void resetEnforceDeviceRestriction() throws Exception {
setEnforceDeviceRestriction(true);
}