Loading core/java/android/window/DesktopExperienceFlags.java +54 −6 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ import static com.android.server.display.feature.flags.Flags.enableDisplayConten import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; import android.content.Context; import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Log; import com.android.internal.R; import com.android.window.flags.Flags; import java.util.ArrayList; Loading Loading @@ -204,6 +207,25 @@ public enum DesktopExperienceFlags { // go/keep-sorted end ; /** Whether the desktop experience developer option is supported. */ static boolean isDesktopExperienceDevOptionSupported() { if (!Flags.showDesktopExperienceDevOption()) { return false; } boolean shouldEnforceDeviceRestrictions = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); if (!shouldEnforceDeviceRestrictions) { return true; } final Context context = getApplicationContext(); if (context == null) { return false; } // Simplified version of DesktopModeHelper.isDeviceEligibleForDesktopMode, as the // developer option cannot be considered when we check eligibility. return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported); } /** * Flag class, to be used in case the enum cannot be used because the flag is not accessible. * Loading Loading @@ -273,6 +295,10 @@ public enum DesktopExperienceFlags { @Nullable private static Boolean sCachedToggleOverride; // Local cache for the application context. @Nullable private static Context sApplicationContext; /** * Local cache of dynamically defined flag, organised by name. * Loading Loading @@ -321,9 +347,7 @@ public enum DesktopExperienceFlags { private static boolean isFlagTrue( BooleanSupplier flagFunction, boolean shouldOverrideByDevOption) { if (Flags.showDesktopExperienceDevOption() && shouldOverrideByDevOption && getToggleOverride()) { if (shouldOverrideByDevOption && getToggleOverride()) { return true; } return flagFunction.getAsBoolean(); Loading Loading @@ -359,14 +383,38 @@ public enum DesktopExperienceFlags { } // Otherwise, fetch and cache it boolean override = getToggleOverrideFromSystem(); boolean override = isToggleOverriddenBySystem(); sCachedToggleOverride = override; Log.d(TAG, "Toggle override initialized to: " + override); return override; } /** Returns the {@link ToggleOverride} from the system property.. */ private static boolean getToggleOverrideFromSystem() { static Context getApplicationContext() { if (sApplicationContext == null) { final Context application = ActivityThread.currentApplication(); if (application == null) { Log.w(TAG, "Could not get the current application."); return null; } sApplicationContext = application; } return sApplicationContext; } /** Returns whether the toggle is overridden by the relevant system property.. */ private static boolean isToggleOverriddenBySystem() { // We never override if display content mode management is enabled. if (enableDisplayContentModeManagement()) { return false; } final Context context = getApplicationContext(); if (context == null) { return false; } // If the developer option is not supported, we don't override. if (!isDesktopExperienceDevOptionSupported()) { return false; } return SystemProperties.getBoolean(SYSTEM_PROPERTY_NAME, false); } } Loading core/java/android/window/DesktopModeFlags.java +54 −44 Original line number Diff line number Diff line Loading @@ -16,13 +16,9 @@ package android.window; import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement; import android.annotation.Nullable; import android.app.ActivityThread; import android.app.Application; import android.content.ContentResolver; import android.os.SystemProperties; import android.content.Context; import android.provider.Settings; import android.util.Log; Loading Loading @@ -191,8 +187,7 @@ public enum DesktopModeFlags { // Local cache for toggle override, which is initialized once on its first access. It needs to // be refreshed only on reboots as overridden state is expected to take effect on reboots. private static ToggleOverride sCachedToggleOverride; public static final String SYSTEM_PROPERTY_NAME = "persist.wm.debug.desktop_experience_devopts"; private static ToggleOverride sCachedRawToggleOverride; DesktopModeFlags(BooleanSupplier flagFunction, boolean shouldOverrideByDevOption) { this.mFlagFunction = flagFunction; Loading @@ -208,77 +203,92 @@ public enum DesktopModeFlags { } public static boolean isDesktopModeForcedEnabled() { return getToggleOverride() == ToggleOverride.OVERRIDE_ON; return getRawToggleOverride() == ToggleOverride.OVERRIDE_ON; } private static boolean isFlagTrue(BooleanSupplier flagFunction, boolean shouldOverrideByDevOption) { if (!shouldOverrideByDevOption) return flagFunction.getAsBoolean(); if (Flags.showDesktopExperienceDevOption()) { // If the feature is enabled, just return the flag's value. if (enableDisplayContentModeManagement()) { return flagFunction.getAsBoolean(); } return switch (getToggleOverride()) { case OVERRIDE_UNSET, OVERRIDE_OFF -> flagFunction.getAsBoolean(); case OVERRIDE_ON -> true; }; } if (Flags.showDesktopWindowingDevOption()) { boolean shouldToggleBeEnabledByDefault = Flags.enableDesktopWindowingMode(); return switch (getToggleOverride()) { case OVERRIDE_UNSET -> flagFunction.getAsBoolean(); // When toggle override matches its default state, don't override flags. This // helps users reset their feature overrides. case OVERRIDE_OFF -> !shouldToggleBeEnabledByDefault && flagFunction.getAsBoolean(); case OVERRIDE_ON -> !shouldToggleBeEnabledByDefault || flagFunction.getAsBoolean(); case OVERRIDE_OFF -> false; case OVERRIDE_ON -> true; }; } return flagFunction.getAsBoolean(); } private static ToggleOverride getToggleOverride() { // If cached, return it if (sCachedToggleOverride != null) { return sCachedToggleOverride; } ToggleOverride override; // Otherwise, fetch and cache it ToggleOverride override = getToggleOverrideFromSystem(); sCachedToggleOverride = override; if (sCachedRawToggleOverride == null) { override = getToggleOverrideFromSystem(); sCachedRawToggleOverride = override; } else { override = sCachedRawToggleOverride; } // Override if the feature (i.e. enableDesktopWindowingMode) and the toggle are opposite. // That is, if desktop windowing mode is enabled but the toggle is disabled, we disable all // the flags while if desktop windowing mode is disabled but the toggle is enabled, we // enable all the flags. // If desktop windowing mode and the toggle agree or if the toggle is not set, we don't // touch the flags. ToggleOverride resolvedOverride; if (Flags.enableDesktopWindowingMode() && override == ToggleOverride.OVERRIDE_OFF) { resolvedOverride = ToggleOverride.OVERRIDE_OFF; } else if (!Flags.enableDesktopWindowingMode() && override == ToggleOverride.OVERRIDE_ON) { resolvedOverride = ToggleOverride.OVERRIDE_ON; } else { resolvedOverride = ToggleOverride.OVERRIDE_UNSET; } sCachedToggleOverride = resolvedOverride; Log.d(TAG, "Toggle override initialized to: " + override); return override; return resolvedOverride; } private static ToggleOverride getRawToggleOverride() { if (sCachedRawToggleOverride != null) { return sCachedRawToggleOverride; } getToggleOverride(); return sCachedRawToggleOverride; } /** * Returns {@link ToggleOverride} from Settings.Global set by toggle. */ private static ToggleOverride getToggleOverrideFromSystem() { int settingValue; if (Flags.showDesktopExperienceDevOption()) { settingValue = SystemProperties.getInt( SYSTEM_PROPERTY_NAME, ToggleOverride.OVERRIDE_UNSET.getSetting() ); } else { final Application application = ActivityThread.currentApplication(); if (application == null) { if (DesktopExperienceFlags.isDesktopExperienceDevOptionSupported()) { if (DesktopExperienceFlags.getToggleOverride()) { return ToggleOverride.OVERRIDE_ON; } return ToggleOverride.OVERRIDE_UNSET; } if (Flags.showDesktopWindowingDevOption()) { final Context context = DesktopExperienceFlags.getApplicationContext(); if (context == null) { Log.w(TAG, "Could not get the current application."); return ToggleOverride.OVERRIDE_UNSET; } final ContentResolver contentResolver = application.getContentResolver(); final ContentResolver contentResolver = context.getContentResolver(); if (contentResolver == null) { Log.w(TAG, "Could not get the content resolver for the application."); return ToggleOverride.OVERRIDE_UNSET; } settingValue = Settings.Global.getInt( int settingValue = Settings.Global.getInt( contentResolver, Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, ToggleOverride.OVERRIDE_UNSET.getSetting() ); } return ToggleOverride.fromSetting(settingValue, ToggleOverride.OVERRIDE_UNSET); } return ToggleOverride.OVERRIDE_UNSET; } /** Override state of desktop mode developer option toggle. */ public enum ToggleOverride { OVERRIDE_UNSET, Loading core/tests/coretests/src/android/window/DesktopExperienceFlagsTest.java +29 −2 Original line number Diff line number Diff line Loading @@ -23,7 +23,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.FlagsParameterization; Loading @@ -34,6 +39,7 @@ import android.window.DesktopExperienceFlags.DesktopExperienceFlag; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.R; import com.android.window.flags.Flags; import org.junit.After; Loading Loading @@ -79,7 +85,10 @@ public class DesktopExperienceFlagsTest { private static final String OVERRIDE_OFF_SETTING = "0"; private static final String OVERRIDE_ON_SETTING = "1"; private Map<String, String> mInitialSyspropValues = null; private Map<String, String> mInitialSyspropValues = new HashMap<>(); private Context mMockContext; private Resources mMockResources; public DesktopExperienceFlagsTest(FlagsParameterization flags) { mSetFlagsRule = new SetFlagsRule(flags); Loading @@ -87,7 +96,19 @@ public class DesktopExperienceFlagsTest { @Before public void setUp() throws Exception { mInitialSyspropValues = new HashMap<>(); mInitialSyspropValues.clear(); mMockResources = mock(Resources.class); mMockContext = mock(Context.class); when(mMockContext.getResources()).thenReturn(mMockResources); setDesktopModeSupported(false); // Set the application context to the mock one Field cachedToggleOverride = DesktopExperienceFlags.class.getDeclaredField("sApplicationContext"); cachedToggleOverride.setAccessible(true); cachedToggleOverride.set(null, mMockContext); mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); setSysProp(DesktopExperienceFlags.SYSTEM_PROPERTY_NAME, null); } Loading Loading @@ -128,6 +149,7 @@ public class DesktopExperienceFlagsTest { @Test public void isTrue_devOptionEnabled_overrideOn_featureFlagOff() throws Exception { assumeTrue(Flags.showDesktopExperienceDevOption()); setDesktopModeSupported(true); mLocalFlagValue = false; setSysProp(DesktopExperienceFlags.SYSTEM_PROPERTY_NAME, OVERRIDE_ON_SETTING); Loading Loading @@ -170,4 +192,9 @@ public class DesktopExperienceFlagsTest { cachedToggleOverride.setAccessible(true); cachedToggleOverride.set(null, null); } private void setDesktopModeSupported(boolean isSupported) { when(mMockResources.getBoolean(eq(R.bool.config_isDesktopModeSupported))).thenReturn( isSupported); } } core/tests/coretests/src/android/window/DesktopModeFlagsTest.java +107 −11 File changed.Preview size limit exceeded, changes collapsed. Show changes libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt +40 −4 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ class DesktopModeStatusTest : ShellTestCase() { @Before fun setUp() { doReturn(mockResources).whenever(mockContext).getResources() doReturn(mockResources).whenever(mockContext).resources setDeviceEligibleForDesktopMode(false) doReturn(false).whenever(mockResources).getBoolean( eq(R.bool.config_isDesktopModeDevOptionSupported) Loading Loading @@ -122,6 +122,20 @@ class DesktopModeStatusTest : ShellTestCase() { assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue() } @DisableFlags( Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE, Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION ) @Test fun canEnterDesktopMode_DWFlagDisabled_deviceNotEligible_forceNotUsingDevOption_returnsFalse() { doReturn(true).whenever(mockResources).getBoolean( eq(R.bool.config_isDesktopModeDevOptionSupported) ) setFlagOverride(DesktopModeFlags.ToggleOverride.OVERRIDE_OFF) assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse() } @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION) @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) @Test Loading Loading @@ -189,6 +203,20 @@ class DesktopModeStatusTest : ShellTestCase() { assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue() } @EnableFlags( Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE, Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION ) @Test fun canEnterDesktopMode_DWFlagEnabled_deviceNotEligible_forceNotUsingDevOption_returnsFalse() { doReturn(true).whenever(mockResources).getBoolean( eq(R.bool.config_isDesktopModeDevOptionSupported) ) setFlagOverride(DesktopModeFlags.ToggleOverride.OVERRIDE_OFF) assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse() } @Test fun isDeviceEligibleForDesktopMode_configDEModeOnAndIntDispHostsDesktop_returnsTrue() { doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported)) Loading Loading @@ -284,11 +312,17 @@ class DesktopModeStatusTest : ShellTestCase() { } private fun resetDesktopModeFlagsCache() { // Toggle raw override cache for DesktopModeFlags val cachedRawToggleOverride1 = DesktopModeFlags::class.java.getDeclaredField("sCachedRawToggleOverride") cachedRawToggleOverride1.isAccessible = true cachedRawToggleOverride1.set(null, DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET) // Toggle override cache for DesktopModeFlags val cachedToggleOverride1 = DesktopModeFlags::class.java.getDeclaredField("sCachedToggleOverride") cachedToggleOverride1.isAccessible = true cachedToggleOverride1.set(null, DesktopModeFlags.ToggleOverride.OVERRIDE_OFF) cachedToggleOverride1.set(null, null) // Toggle override cache for DesktopExperienceFlags val cachedToggleOverride2 = Loading @@ -298,9 +332,11 @@ class DesktopModeStatusTest : ShellTestCase() { } private fun setFlagOverride(override: DesktopModeFlags.ToggleOverride) { // Toggle override cache for DesktopModeFlags can be on/off/unset resetDesktopModeFlagsCache() // Toggle raw override cache for DesktopModeFlags can be on/off/unset val cachedToggleOverride1 = DesktopModeFlags::class.java.getDeclaredField("sCachedToggleOverride") DesktopModeFlags::class.java.getDeclaredField("sCachedRawToggleOverride") cachedToggleOverride1.isAccessible = true cachedToggleOverride1.set(null, override) Loading Loading
core/java/android/window/DesktopExperienceFlags.java +54 −6 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ import static com.android.server.display.feature.flags.Flags.enableDisplayConten import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; import android.content.Context; import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Log; import com.android.internal.R; import com.android.window.flags.Flags; import java.util.ArrayList; Loading Loading @@ -204,6 +207,25 @@ public enum DesktopExperienceFlags { // go/keep-sorted end ; /** Whether the desktop experience developer option is supported. */ static boolean isDesktopExperienceDevOptionSupported() { if (!Flags.showDesktopExperienceDevOption()) { return false; } boolean shouldEnforceDeviceRestrictions = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); if (!shouldEnforceDeviceRestrictions) { return true; } final Context context = getApplicationContext(); if (context == null) { return false; } // Simplified version of DesktopModeHelper.isDeviceEligibleForDesktopMode, as the // developer option cannot be considered when we check eligibility. return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported); } /** * Flag class, to be used in case the enum cannot be used because the flag is not accessible. * Loading Loading @@ -273,6 +295,10 @@ public enum DesktopExperienceFlags { @Nullable private static Boolean sCachedToggleOverride; // Local cache for the application context. @Nullable private static Context sApplicationContext; /** * Local cache of dynamically defined flag, organised by name. * Loading Loading @@ -321,9 +347,7 @@ public enum DesktopExperienceFlags { private static boolean isFlagTrue( BooleanSupplier flagFunction, boolean shouldOverrideByDevOption) { if (Flags.showDesktopExperienceDevOption() && shouldOverrideByDevOption && getToggleOverride()) { if (shouldOverrideByDevOption && getToggleOverride()) { return true; } return flagFunction.getAsBoolean(); Loading Loading @@ -359,14 +383,38 @@ public enum DesktopExperienceFlags { } // Otherwise, fetch and cache it boolean override = getToggleOverrideFromSystem(); boolean override = isToggleOverriddenBySystem(); sCachedToggleOverride = override; Log.d(TAG, "Toggle override initialized to: " + override); return override; } /** Returns the {@link ToggleOverride} from the system property.. */ private static boolean getToggleOverrideFromSystem() { static Context getApplicationContext() { if (sApplicationContext == null) { final Context application = ActivityThread.currentApplication(); if (application == null) { Log.w(TAG, "Could not get the current application."); return null; } sApplicationContext = application; } return sApplicationContext; } /** Returns whether the toggle is overridden by the relevant system property.. */ private static boolean isToggleOverriddenBySystem() { // We never override if display content mode management is enabled. if (enableDisplayContentModeManagement()) { return false; } final Context context = getApplicationContext(); if (context == null) { return false; } // If the developer option is not supported, we don't override. if (!isDesktopExperienceDevOptionSupported()) { return false; } return SystemProperties.getBoolean(SYSTEM_PROPERTY_NAME, false); } } Loading
core/java/android/window/DesktopModeFlags.java +54 −44 Original line number Diff line number Diff line Loading @@ -16,13 +16,9 @@ package android.window; import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement; import android.annotation.Nullable; import android.app.ActivityThread; import android.app.Application; import android.content.ContentResolver; import android.os.SystemProperties; import android.content.Context; import android.provider.Settings; import android.util.Log; Loading Loading @@ -191,8 +187,7 @@ public enum DesktopModeFlags { // Local cache for toggle override, which is initialized once on its first access. It needs to // be refreshed only on reboots as overridden state is expected to take effect on reboots. private static ToggleOverride sCachedToggleOverride; public static final String SYSTEM_PROPERTY_NAME = "persist.wm.debug.desktop_experience_devopts"; private static ToggleOverride sCachedRawToggleOverride; DesktopModeFlags(BooleanSupplier flagFunction, boolean shouldOverrideByDevOption) { this.mFlagFunction = flagFunction; Loading @@ -208,77 +203,92 @@ public enum DesktopModeFlags { } public static boolean isDesktopModeForcedEnabled() { return getToggleOverride() == ToggleOverride.OVERRIDE_ON; return getRawToggleOverride() == ToggleOverride.OVERRIDE_ON; } private static boolean isFlagTrue(BooleanSupplier flagFunction, boolean shouldOverrideByDevOption) { if (!shouldOverrideByDevOption) return flagFunction.getAsBoolean(); if (Flags.showDesktopExperienceDevOption()) { // If the feature is enabled, just return the flag's value. if (enableDisplayContentModeManagement()) { return flagFunction.getAsBoolean(); } return switch (getToggleOverride()) { case OVERRIDE_UNSET, OVERRIDE_OFF -> flagFunction.getAsBoolean(); case OVERRIDE_ON -> true; }; } if (Flags.showDesktopWindowingDevOption()) { boolean shouldToggleBeEnabledByDefault = Flags.enableDesktopWindowingMode(); return switch (getToggleOverride()) { case OVERRIDE_UNSET -> flagFunction.getAsBoolean(); // When toggle override matches its default state, don't override flags. This // helps users reset their feature overrides. case OVERRIDE_OFF -> !shouldToggleBeEnabledByDefault && flagFunction.getAsBoolean(); case OVERRIDE_ON -> !shouldToggleBeEnabledByDefault || flagFunction.getAsBoolean(); case OVERRIDE_OFF -> false; case OVERRIDE_ON -> true; }; } return flagFunction.getAsBoolean(); } private static ToggleOverride getToggleOverride() { // If cached, return it if (sCachedToggleOverride != null) { return sCachedToggleOverride; } ToggleOverride override; // Otherwise, fetch and cache it ToggleOverride override = getToggleOverrideFromSystem(); sCachedToggleOverride = override; if (sCachedRawToggleOverride == null) { override = getToggleOverrideFromSystem(); sCachedRawToggleOverride = override; } else { override = sCachedRawToggleOverride; } // Override if the feature (i.e. enableDesktopWindowingMode) and the toggle are opposite. // That is, if desktop windowing mode is enabled but the toggle is disabled, we disable all // the flags while if desktop windowing mode is disabled but the toggle is enabled, we // enable all the flags. // If desktop windowing mode and the toggle agree or if the toggle is not set, we don't // touch the flags. ToggleOverride resolvedOverride; if (Flags.enableDesktopWindowingMode() && override == ToggleOverride.OVERRIDE_OFF) { resolvedOverride = ToggleOverride.OVERRIDE_OFF; } else if (!Flags.enableDesktopWindowingMode() && override == ToggleOverride.OVERRIDE_ON) { resolvedOverride = ToggleOverride.OVERRIDE_ON; } else { resolvedOverride = ToggleOverride.OVERRIDE_UNSET; } sCachedToggleOverride = resolvedOverride; Log.d(TAG, "Toggle override initialized to: " + override); return override; return resolvedOverride; } private static ToggleOverride getRawToggleOverride() { if (sCachedRawToggleOverride != null) { return sCachedRawToggleOverride; } getToggleOverride(); return sCachedRawToggleOverride; } /** * Returns {@link ToggleOverride} from Settings.Global set by toggle. */ private static ToggleOverride getToggleOverrideFromSystem() { int settingValue; if (Flags.showDesktopExperienceDevOption()) { settingValue = SystemProperties.getInt( SYSTEM_PROPERTY_NAME, ToggleOverride.OVERRIDE_UNSET.getSetting() ); } else { final Application application = ActivityThread.currentApplication(); if (application == null) { if (DesktopExperienceFlags.isDesktopExperienceDevOptionSupported()) { if (DesktopExperienceFlags.getToggleOverride()) { return ToggleOverride.OVERRIDE_ON; } return ToggleOverride.OVERRIDE_UNSET; } if (Flags.showDesktopWindowingDevOption()) { final Context context = DesktopExperienceFlags.getApplicationContext(); if (context == null) { Log.w(TAG, "Could not get the current application."); return ToggleOverride.OVERRIDE_UNSET; } final ContentResolver contentResolver = application.getContentResolver(); final ContentResolver contentResolver = context.getContentResolver(); if (contentResolver == null) { Log.w(TAG, "Could not get the content resolver for the application."); return ToggleOverride.OVERRIDE_UNSET; } settingValue = Settings.Global.getInt( int settingValue = Settings.Global.getInt( contentResolver, Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, ToggleOverride.OVERRIDE_UNSET.getSetting() ); } return ToggleOverride.fromSetting(settingValue, ToggleOverride.OVERRIDE_UNSET); } return ToggleOverride.OVERRIDE_UNSET; } /** Override state of desktop mode developer option toggle. */ public enum ToggleOverride { OVERRIDE_UNSET, Loading
core/tests/coretests/src/android/window/DesktopExperienceFlagsTest.java +29 −2 Original line number Diff line number Diff line Loading @@ -23,7 +23,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.FlagsParameterization; Loading @@ -34,6 +39,7 @@ import android.window.DesktopExperienceFlags.DesktopExperienceFlag; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.R; import com.android.window.flags.Flags; import org.junit.After; Loading Loading @@ -79,7 +85,10 @@ public class DesktopExperienceFlagsTest { private static final String OVERRIDE_OFF_SETTING = "0"; private static final String OVERRIDE_ON_SETTING = "1"; private Map<String, String> mInitialSyspropValues = null; private Map<String, String> mInitialSyspropValues = new HashMap<>(); private Context mMockContext; private Resources mMockResources; public DesktopExperienceFlagsTest(FlagsParameterization flags) { mSetFlagsRule = new SetFlagsRule(flags); Loading @@ -87,7 +96,19 @@ public class DesktopExperienceFlagsTest { @Before public void setUp() throws Exception { mInitialSyspropValues = new HashMap<>(); mInitialSyspropValues.clear(); mMockResources = mock(Resources.class); mMockContext = mock(Context.class); when(mMockContext.getResources()).thenReturn(mMockResources); setDesktopModeSupported(false); // Set the application context to the mock one Field cachedToggleOverride = DesktopExperienceFlags.class.getDeclaredField("sApplicationContext"); cachedToggleOverride.setAccessible(true); cachedToggleOverride.set(null, mMockContext); mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); setSysProp(DesktopExperienceFlags.SYSTEM_PROPERTY_NAME, null); } Loading Loading @@ -128,6 +149,7 @@ public class DesktopExperienceFlagsTest { @Test public void isTrue_devOptionEnabled_overrideOn_featureFlagOff() throws Exception { assumeTrue(Flags.showDesktopExperienceDevOption()); setDesktopModeSupported(true); mLocalFlagValue = false; setSysProp(DesktopExperienceFlags.SYSTEM_PROPERTY_NAME, OVERRIDE_ON_SETTING); Loading Loading @@ -170,4 +192,9 @@ public class DesktopExperienceFlagsTest { cachedToggleOverride.setAccessible(true); cachedToggleOverride.set(null, null); } private void setDesktopModeSupported(boolean isSupported) { when(mMockResources.getBoolean(eq(R.bool.config_isDesktopModeSupported))).thenReturn( isSupported); } }
core/tests/coretests/src/android/window/DesktopModeFlagsTest.java +107 −11 File changed.Preview size limit exceeded, changes collapsed. Show changes
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt +40 −4 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ class DesktopModeStatusTest : ShellTestCase() { @Before fun setUp() { doReturn(mockResources).whenever(mockContext).getResources() doReturn(mockResources).whenever(mockContext).resources setDeviceEligibleForDesktopMode(false) doReturn(false).whenever(mockResources).getBoolean( eq(R.bool.config_isDesktopModeDevOptionSupported) Loading Loading @@ -122,6 +122,20 @@ class DesktopModeStatusTest : ShellTestCase() { assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue() } @DisableFlags( Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE, Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION ) @Test fun canEnterDesktopMode_DWFlagDisabled_deviceNotEligible_forceNotUsingDevOption_returnsFalse() { doReturn(true).whenever(mockResources).getBoolean( eq(R.bool.config_isDesktopModeDevOptionSupported) ) setFlagOverride(DesktopModeFlags.ToggleOverride.OVERRIDE_OFF) assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse() } @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION) @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) @Test Loading Loading @@ -189,6 +203,20 @@ class DesktopModeStatusTest : ShellTestCase() { assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue() } @EnableFlags( Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE, Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION ) @Test fun canEnterDesktopMode_DWFlagEnabled_deviceNotEligible_forceNotUsingDevOption_returnsFalse() { doReturn(true).whenever(mockResources).getBoolean( eq(R.bool.config_isDesktopModeDevOptionSupported) ) setFlagOverride(DesktopModeFlags.ToggleOverride.OVERRIDE_OFF) assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse() } @Test fun isDeviceEligibleForDesktopMode_configDEModeOnAndIntDispHostsDesktop_returnsTrue() { doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported)) Loading Loading @@ -284,11 +312,17 @@ class DesktopModeStatusTest : ShellTestCase() { } private fun resetDesktopModeFlagsCache() { // Toggle raw override cache for DesktopModeFlags val cachedRawToggleOverride1 = DesktopModeFlags::class.java.getDeclaredField("sCachedRawToggleOverride") cachedRawToggleOverride1.isAccessible = true cachedRawToggleOverride1.set(null, DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET) // Toggle override cache for DesktopModeFlags val cachedToggleOverride1 = DesktopModeFlags::class.java.getDeclaredField("sCachedToggleOverride") cachedToggleOverride1.isAccessible = true cachedToggleOverride1.set(null, DesktopModeFlags.ToggleOverride.OVERRIDE_OFF) cachedToggleOverride1.set(null, null) // Toggle override cache for DesktopExperienceFlags val cachedToggleOverride2 = Loading @@ -298,9 +332,11 @@ class DesktopModeStatusTest : ShellTestCase() { } private fun setFlagOverride(override: DesktopModeFlags.ToggleOverride) { // Toggle override cache for DesktopModeFlags can be on/off/unset resetDesktopModeFlagsCache() // Toggle raw override cache for DesktopModeFlags can be on/off/unset val cachedToggleOverride1 = DesktopModeFlags::class.java.getDeclaredField("sCachedToggleOverride") DesktopModeFlags::class.java.getDeclaredField("sCachedRawToggleOverride") cachedToggleOverride1.isAccessible = true cachedToggleOverride1.set(null, override) Loading