diff --git a/res/values/strings.xml b/res/values/strings.xml index af7473b3c8e..96dc07ebbaa 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12201,10 +12201,17 @@ Settings Panel - - Force desktop mode - - Force experimental desktop mode on secondary displays + + Enable freeform windows + + Enable support for freeform windows. + + + + Enable freeform windowing on second display + + Enable freeform windows only on secondary display. + Enable non-resizable in multi window @@ -13168,12 +13175,12 @@ - A reboot is required to enable freeform - support. - - A reboot is required to force desktop mode on - secondary displays. + A reboot is required to enable legacy freeform windowing support. + + A reboot is required to change freeform windowing support. + + A reboot is required to force freeform windowing on secondary displays. Reboot now diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 866a529dd8b..9420f59e881 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -737,6 +737,11 @@ android:title="@string/force_resizable_activities" android:summary="@string/force_resizable_activities_summary" /> + + false; + case SETTING_VALUE_ON -> true; + case SETTING_VALUE_UNSET -> shouldDevOptionBeEnabledByDefault; + default -> { + Log.w(TAG, "Invalid override for desktop mode: " + mode); + yield shouldDevOptionBeEnabledByDefault; + } + }; + ((TwoStatePreference) mPreference).setChecked(shouldDevOptionBeEnabled); } @Override protected void onDeveloperOptionsSwitchDisabled() { super.onDeveloperOptionsSwitchDisabled(); Settings.Global.putInt(mContext.getContentResolver(), - DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF); - ((TwoStatePreference) mPreference).setChecked(false); + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, SETTING_VALUE_UNSET); } - @VisibleForTesting - String getBuildType() { - return Build.TYPE; + private boolean isDeviceEligibleForDesktopMode() { + boolean enforceDeviceRestrictions = SystemProperties.getBoolean( + "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); + boolean isDesktopModeSupported = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_isDesktopModeSupported); + return !enforceDeviceRestrictions || isDesktopModeSupported; } } diff --git a/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java b/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java new file mode 100644 index 00000000000..ff513c249f5 --- /dev/null +++ b/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; + +import android.content.Context; +import android.os.Build; +import android.provider.Settings; + +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.TwoStatePreference; + +import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +/** + * Preference controller to control Desktop mode features on secondary display + */ +public class DesktopModeSecondaryDisplayPreferenceController extends + DeveloperOptionsPreferenceController + implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin, + RebootConfirmationDialogHost { + + private static final String ENABLE_DESKTOP_MODE_ON_SECONDARY_DISPLAY = + "force_desktop_mode_on_external_displays"; + + @VisibleForTesting + static final int SETTING_VALUE_OFF = 0; + @VisibleForTesting + static final int SETTING_VALUE_ON = 1; + + @Nullable + private final DevelopmentSettingsDashboardFragment mFragment; + + public DesktopModeSecondaryDisplayPreferenceController( + Context context, @Nullable DevelopmentSettingsDashboardFragment fragment) { + super(context); + mFragment = fragment; + } + + @Override + public String getPreferenceKey() { + return ENABLE_DESKTOP_MODE_ON_SECONDARY_DISPLAY; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean isEnabled = (Boolean) newValue; + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, + isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF); + if (isEnabled && mFragment != null) { + RebootConfirmationDialogFragment.show( + mFragment, R.string.reboot_dialog_force_desktop_mode, this); + } + return true; + } + + @Override + public void updateState(Preference preference) { + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF); + ((TwoStatePreference) mPreference).setChecked(mode != SETTING_VALUE_OFF); + } + + @Override + protected void onDeveloperOptionsSwitchDisabled() { + super.onDeveloperOptionsSwitchDisabled(); + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF); + ((TwoStatePreference) mPreference).setChecked(false); + } + + @VisibleForTesting + String getBuildType() { + return Build.TYPE; + } +} diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 38cb6c72e96..0389b4521fb 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -749,6 +749,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new ResizableActivityPreferenceController(context)); controllers.add(new FreeformWindowsPreferenceController(context, fragment)); controllers.add(new DesktopModePreferenceController(context, fragment)); + controllers.add(new DesktopModeSecondaryDisplayPreferenceController(context, fragment)); controllers.add(new NonResizableMultiWindowPreferenceController(context)); controllers.add(new ShortcutManagerThrottlingPreferenceController(context)); controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context)); diff --git a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java index 460f6f9bc08..c74512a502a 100644 --- a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,11 @@ package com.android.settings.development; -import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; +import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES; import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_OFF; import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_ON; +import static com.android.settings.development.DesktopModePreferenceController.SETTING_VALUE_UNSET; import static com.google.common.truth.Truth.assertThat; @@ -30,6 +31,10 @@ import static org.mockito.Mockito.verify; 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.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import androidx.fragment.app.FragmentActivity; @@ -37,24 +42,30 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; + +import com.android.internal.R; +import com.android.window.flags.Flags; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowSystemProperties; @RunWith(RobolectricTestRunner.class) @Config(shadows = { com.android.settings.testutils.shadow.ShadowFragment.class, }) +@EnableFlags(Flags.FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION) public class DesktopModePreferenceControllerTest { - private static final String ENG_BUILD_TYPE = "eng"; - private static final String USER_BUILD_TYPE = "user"; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private SwitchPreference mPreference; @@ -69,61 +80,76 @@ public class DesktopModePreferenceControllerTest { @Mock private FragmentTransaction mTransaction; + private Resources mResources; private Context mContext; private DesktopModePreferenceController mController; @Before public void setup() { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + + mContext = spy(ApplicationProvider.getApplicationContext()); doReturn(mTransaction).when(mFragmentManager).beginTransaction(); doReturn(mFragmentManager).when(mActivity).getSupportFragmentManager(); doReturn(mActivity).when(mFragment).getActivity(); + + mResources = spy(mContext.getResources()); + when(mContext.getResources()).thenReturn(mResources); + mController = new DesktopModePreferenceController(mContext, mFragment); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); mController.displayPreference(mScreen); + + // Set desktop mode available + when(mResources.getBoolean(R.bool.config_isDesktopModeSupported)) + .thenReturn(true); + ShadowSystemProperties.override("persist.wm.debug.desktop_mode_enforce_device_restrictions", + "false"); } @Test - public void isAvailable_engBuild_shouldBeTrue() { + public void isAvailable_desktopModeDevOptionNotSupported_returnsFalse() { + mController = spy(mController); + // Dev option is not supported if Desktop mode is not supported + when(mResources.getBoolean(R.bool.config_isDesktopModeSupported)).thenReturn(false); + ShadowSystemProperties.override("persist.wm.debug.desktop_mode_enforce_device_restrictions", + "true"); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_desktopModeDevOptionSupported_returnsTrue() { mController = spy(mController); - doReturn(ENG_BUILD_TYPE).when(mController).getBuildType(); assertThat(mController.isAvailable()).isTrue(); } @Test - public void isAvaiable_userBuild_shouldBeTrue() { - mController = spy(mController); - doReturn(USER_BUILD_TYPE).when(mController).getBuildType(); - - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void onPreferenceChange_switchEnabled_shouldEnableDesktopMode() { + public void onPreferenceChange_switchEnabled_putsSettingsOverrideOnAndTriggersRestart() { mController.onPreferenceChange(mPreference, true /* new value */); final int mode = Settings.Global.getInt(mContext.getContentResolver(), - DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */); + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, -1 /* default */); assertThat(mode).isEqualTo(SETTING_VALUE_ON); - verify(mTransaction).add(any(RebootConfirmationDialogFragment.class), any()); } @Test - public void onPreferenceChange_switchDisabled_shouldDisableDesktopMode() { + public void onPreferenceChange_switchDisabled_putsSettingsOverrideOffAndTriggersRestart() { mController.onPreferenceChange(mPreference, false /* new value */); - final int mode = Settings.Global.getInt(mContext.getContentResolver(), - DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */); + int mode = Settings.Global.getInt(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, -1 /* default */); assertThat(mode).isEqualTo(SETTING_VALUE_OFF); + verify(mTransaction).add(any(RebootConfirmationDialogFragment.class), any()); } @Test - public void updateState_settingEnabled_preferenceShouldBeChecked() { + public void updateState_overrideOn_checksPreference() { Settings.Global.putInt(mContext.getContentResolver(), - DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_ON); + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, SETTING_VALUE_ON); mController.updateState(mPreference); @@ -131,9 +157,9 @@ public class DesktopModePreferenceControllerTest { } @Test - public void updateState_settingDisabled_preferenceShouldNotBeChecked() { + public void updateState_overrideOff_unchecksPreference() { Settings.Global.putInt(mContext.getContentResolver(), - DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF); + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, SETTING_VALUE_OFF); mController.updateState(mPreference); @@ -141,12 +167,92 @@ public class DesktopModePreferenceControllerTest { } @Test - public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() { + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) + public void updateState_overrideUnset_defaultDevOptionStatusOn_checksPreference() { + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, SETTING_VALUE_UNSET); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(true); + } + + @Test + @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) + public void updateState_overrideUnset_defaultDevOptionStatusOff_unchecksPreference() { + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, SETTING_VALUE_UNSET); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(false); + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) + public void updateState_noOverride_defaultDevOptionStatusOn_checksPreference() { + // Set no override + Settings.Global.putString(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, null); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(true); + } + + @Test + @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) + public void updateState_noOverride_defaultDevOptionStatusOff_unchecksPreference() { + // Set no override + Settings.Global.putString(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, null); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(false); + } + + @Test + public void updateState_noOverride_noNewSettingsOverride() { + // Set no override + Settings.Global.putString(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, null); + + mController.updateState(mPreference); + + int mode = Settings.Global.getInt(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, -2 /* default */); + assertThat(mode).isEqualTo(-2); + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) + public void updateState_overrideUnknown_defaultDevOptionStatusOn_checksPreference() { + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, -2); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(true); + } + + @Test + @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) + public void updateState_overrideUnknown_defaultDevOptionStatusOff_unchecksPreference() { + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, -2); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(false); + } + + @Test + public void onDeveloperOptionsSwitchDisabled_putsSettingsOverrideOff() { mController.onDeveloperOptionsSwitchDisabled(); final int mode = Settings.Global.getInt(mContext.getContentResolver(), - DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */); - assertThat(mode).isEqualTo(SETTING_VALUE_OFF); - verify(mPreference).setEnabled(false); + DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, -2 /* default */); + assertThat(mode).isEqualTo(DesktopModePreferenceController.SETTING_VALUE_UNSET); } } diff --git a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java new file mode 100644 index 00000000000..5931004cb66 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; + +import static com.android.settings.development.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_OFF; +import static com.android.settings.development.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_ON; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; + +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = { + com.android.settings.testutils.shadow.ShadowFragment.class, +}) +public class DesktopModeSecondaryDisplayPreferenceControllerTest { + + private static final String ENG_BUILD_TYPE = "eng"; + private static final String USER_BUILD_TYPE = "user"; + + @Mock + private SwitchPreference mPreference; + @Mock + private PreferenceScreen mScreen; + @Mock + private DevelopmentSettingsDashboardFragment mFragment; + @Mock + private FragmentActivity mActivity; + @Mock + private FragmentManager mFragmentManager; + @Mock + private FragmentTransaction mTransaction; + + private Context mContext; + private DesktopModeSecondaryDisplayPreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + doReturn(mTransaction).when(mFragmentManager).beginTransaction(); + doReturn(mFragmentManager).when(mActivity).getSupportFragmentManager(); + doReturn(mActivity).when(mFragment).getActivity(); + mController = new DesktopModeSecondaryDisplayPreferenceController(mContext, mFragment); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + mController.displayPreference(mScreen); + } + + @Test + public void isAvailable_engBuild_shouldBeTrue() { + mController = spy(mController); + doReturn(ENG_BUILD_TYPE).when(mController).getBuildType(); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_userBuild_shouldBeTrue() { + mController = spy(mController); + doReturn(USER_BUILD_TYPE).when(mController).getBuildType(); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void onPreferenceChange_switchEnabled_enablesDesktopModeOnSecondaryDisplay() { + mController.onPreferenceChange(mPreference, true /* new value */); + + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */); + assertThat(mode).isEqualTo(SETTING_VALUE_ON); + + verify(mTransaction).add(any(RebootConfirmationDialogFragment.class), any()); + } + + @Test + public void onPreferenceChange_switchDisabled_disablesDesktopModeOnSecondaryDisplay() { + mController.onPreferenceChange(mPreference, false /* new value */); + + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */); + assertThat(mode).isEqualTo(SETTING_VALUE_OFF); + } + + @Test + public void updateState_settingEnabled_checksPreference() { + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_ON); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(true); + } + + @Test + public void updateState_settingDisabled_unchecksPreference() { + Settings.Global.putInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, SETTING_VALUE_OFF); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(false); + } + + @Test + public void onDeveloperOptionsSwitchDisabled_disablesPreference() { + mController.onDeveloperOptionsSwitchDisabled(); + + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, -1 /* default */); + assertThat(mode).isEqualTo(SETTING_VALUE_OFF); + verify(mPreference).setEnabled(false); + } +}