diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java index 3718fab212f..2b92e50a2b7 100644 --- a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java @@ -18,12 +18,13 @@ package com.android.settings.connecteddevice.display; import static android.view.Display.INVALID_DISPLAY; -import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.EXTERNAL_DISPLAY_HELP_URL; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.DISPLAY_ID_ARG; +import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.EXTERNAL_DISPLAY_HELP_URL; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.EXTERNAL_DISPLAY_NOT_FOUND_RESOURCE; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isDisplayAllowed; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isTopologyPaneEnabled; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isUseDisplaySettingEnabled; +import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isDisplaySizeSettingEnabled; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isResolutionSettingEnabled; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isRotationSettingEnabled; @@ -45,6 +46,7 @@ import androidx.preference.PreferenceGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragmentBase; +import com.android.settings.accessibility.AccessibilitySeekBarPreference; import com.android.settings.accessibility.TextReadingPreferenceFragment; import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.DisplayListener; import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.Injector; @@ -68,6 +70,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen static final String EXTERNAL_DISPLAY_USE_PREFERENCE_KEY = "external_display_use_preference"; static final String EXTERNAL_DISPLAY_ROTATION_KEY = "external_display_rotation"; static final String EXTERNAL_DISPLAY_RESOLUTION_PREFERENCE_KEY = "external_display_resolution"; + static final String EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY = "external_display_size"; static final int EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE = R.string.external_display_change_resolution_footer_title; static final int EXTERNAL_DISPLAY_LANDSCAPE_DRAWABLE = @@ -84,6 +87,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen R.string.external_display_rotation; static final int EXTERNAL_DISPLAY_RESOLUTION_TITLE_RESOURCE = R.string.external_display_resolution_settings_title; + static final int EXTERNAL_DISPLAY_SIZE_TITLE_RESOURCE = R.string.screen_zoom_title; + static final int EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE = R.string.screen_zoom_short_summary; static final int BUILTIN_DISPLAY_SETTINGS_CATEGORY_RESOURCE = R.string.builtin_display_settings_category; @VisibleForTesting @@ -111,6 +116,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen private Preference mBuiltinDisplaySizeAndTextPreference; @Nullable private Injector mInjector; + @Nullable private AccessibilitySeekBarPreference mDisplaySizePreference; @Nullable private String[] mRotationEntries; @Nullable @@ -345,6 +351,21 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen return mMirrorPreference; } + @NonNull + @VisibleForTesting + AccessibilitySeekBarPreference getSizePreference(@NonNull Context context) { + if (mDisplaySizePreference == null) { + mDisplaySizePreference = new AccessibilitySeekBarPreference(context, /* attrs= */ null); + mDisplaySizePreference.setIconStart(R.drawable.ic_remove_24dp); + mDisplaySizePreference.setIconStartContentDescription( + R.string.screen_zoom_make_smaller_desc); + mDisplaySizePreference.setIconEnd(R.drawable.ic_add_24dp); + mDisplaySizePreference.setIconEndContentDescription( + R.string.screen_zoom_make_larger_desc); + } + return mDisplaySizePreference; + } + private void restoreState(@Nullable Bundle savedInstanceState) { if (savedInstanceState == null) { return; @@ -428,6 +449,9 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen screen.addPreference(updateFooterPreference(context, EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE)); } + if (isDisplaySizeSettingEnabled(mInjector)) { + screen.addPreference(updateSizePreference(context)); + } } private void showDisplaysList(@NonNull List displaysToShow, @@ -599,6 +623,20 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen return pref; } + private Preference updateSizePreference(@NonNull final Context context) { + var pref = (Preference) getSizePreference(context); + pref.setKey(EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY); + pref.setSummary(EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE); + pref.setPersistent(false); + pref.setTitle(EXTERNAL_DISPLAY_SIZE_TITLE_RESOURCE); + pref.setOnPreferenceClickListener( + (Preference p) -> { + writePreferenceClickMetric(p); + return true; + }); + return pref; + } + private int getDisplayRotation(int displayId) { if (mInjector == null) { return 0; diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java b/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java index 2a1fc12e7ef..666bf37c54a 100644 --- a/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java @@ -353,4 +353,8 @@ public class ExternalDisplaySettingsConfiguration { static boolean isRotationSettingEnabled(@Nullable Injector injector) { return injector != null && injector.getFlags().rotationConnectedDisplaySetting(); } + + static boolean isDisplaySizeSettingEnabled(@Nullable Injector injector) { + return injector != null && injector.getFlags().displaySizeConnectedDisplaySetting(); + } } diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java index 10ddd87f304..d22dbaeed00 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java @@ -17,7 +17,6 @@ package com.android.settings.connecteddevice.display; import static android.view.Display.INVALID_DISPLAY; -import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.PREVIOUSLY_SHOWN_LIST_KEY; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.DISPLAYS_LIST_PREFERENCE_KEY; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE; @@ -26,8 +25,13 @@ import static com.android.settings.connecteddevice.display.ExternalDisplayPrefer import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_ROTATION_KEY; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_ROTATION_TITLE_RESOURCE; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SETTINGS_RESOURCE; +import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY; +import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE; +import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SIZE_TITLE_RESOURCE; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_USE_PREFERENCE_KEY; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_USE_TITLE_RESOURCE; +import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.PREVIOUSLY_SHOWN_LIST_KEY; +import static com.android.settings.flags.Flags.FLAG_DISPLAY_SIZE_CONNECTED_DISPLAY_SETTING; import static com.android.settings.flags.Flags.FLAG_DISPLAY_TOPOLOGY_PANE_IN_DISPLAY_LIST; import static com.android.settingslib.widget.FooterPreference.KEY_FOOTER; @@ -205,6 +209,29 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa assertThat(pref.getPreferenceCount()).isEqualTo(1); } + @Test + @UiThreadTest + public void testShowEnabledDisplay_OnlyOneDisplayAvailable_displaySizeDisabled() { + mFlags.setFlag(FLAG_DISPLAY_SIZE_CONNECTED_DISPLAY_SETTING, false); + doReturn(true).when(mMockedInjector).isDisplayEnabled(any()); + // Only one display available + doReturn(new Display[] {mDisplays[1]}).when(mMockedInjector).getAllDisplays(); + // Init + initFragment(); + mHandler.flush(); + PreferenceCategory list = mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY); + assertThat(list).isNull(); + var pref = mPreferenceScreen.findPreference(EXTERNAL_DISPLAY_RESOLUTION_PREFERENCE_KEY); + assertThat(pref).isNotNull(); + pref = mPreferenceScreen.findPreference(EXTERNAL_DISPLAY_ROTATION_KEY); + assertThat(pref).isNotNull(); + var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER); + assertThat(footerPref).isNotNull(); + var sizePref = mPreferenceScreen.findPreference(EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY); + assertThat(sizePref).isNull(); + verify(footerPref).setTitle(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE); + } + @Test @UiThreadTest public void testShowEnabledDisplay_OnlyOneDisplayAvailable() { @@ -222,6 +249,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa assertThat(pref).isNotNull(); var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER); assertThat(footerPref).isNotNull(); + var sizePref = mPreferenceScreen.findPreference(EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY); + assertThat(sizePref).isNotNull(); verify(footerPref).setTitle(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE); } @@ -240,6 +269,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa assertThat(pref).isNotNull(); var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER); assertThat(footerPref).isNotNull(); + var sizePref = mPreferenceScreen.findPreference(EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY); + assertThat(sizePref).isNotNull(); verify(footerPref).setTitle(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE); } @@ -265,6 +296,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa assertThat(pref).isNull(); var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER); assertThat(footerPref).isNull(); + var sizePref = mPreferenceScreen.findPreference(EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY); + assertThat(sizePref).isNull(); } @Test @@ -337,6 +370,24 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa verify(mMockedMetricsLogger).writePreferenceClickMetric(pref); } + @Test + @UiThreadTest + public void testDisplaySizePreference() { + mDisplayIdArg = 1; + doReturn(true).when(mMockedInjector).isDisplayEnabled(any()); + var fragment = initFragment(); + mHandler.flush(); + var pref = fragment.getSizePreference(mContext); + assertThat(pref.getKey()).isEqualTo(EXTERNAL_DISPLAY_SIZE_PREFERENCE_KEY); + assertThat("" + pref.getTitle()).isEqualTo(getText(EXTERNAL_DISPLAY_SIZE_TITLE_RESOURCE)); + assertThat("" + pref.getSummary()) + .isEqualTo(getText(EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE)); + assertThat(pref.isEnabled()).isTrue(); + assertThat(pref.getOnPreferenceClickListener()).isNotNull(); + assertThat(pref.getOnPreferenceClickListener().onPreferenceClick(pref)).isTrue(); + verify(mMockedMetricsLogger).writePreferenceClickMetric(pref); + } + @Test @UiThreadTest public void testUseDisplayPreference_EnabledDisplay() { diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java index 874ecbd1197..ea76118c5a2 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java @@ -16,6 +16,7 @@ package com.android.settings.connecteddevice.display; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.VIRTUAL_DISPLAY_PACKAGE_NAME_SYSTEM_PROPERTY; +import static com.android.settings.flags.Flags.FLAG_DISPLAY_SIZE_CONNECTED_DISPLAY_SETTING; import static com.android.settings.flags.Flags.FLAG_DISPLAY_TOPOLOGY_PANE_IN_DISPLAY_LIST; import static com.android.settings.flags.Flags.FLAG_RESOLUTION_AND_ENABLE_CONNECTED_DISPLAY_SETTING; import static com.android.settings.flags.Flags.FLAG_ROTATION_CONNECTED_DISPLAY_SETTING; @@ -78,6 +79,7 @@ public class ExternalDisplayTestBase { mFlags.setFlag(FLAG_DISPLAY_TOPOLOGY_PANE_IN_DISPLAY_LIST, false); mFlags.setFlag(FLAG_ROTATION_CONNECTED_DISPLAY_SETTING, true); mFlags.setFlag(FLAG_RESOLUTION_AND_ENABLE_CONNECTED_DISPLAY_SETTING, true); + mFlags.setFlag(FLAG_DISPLAY_SIZE_CONNECTED_DISPLAY_SETTING, true); mDisplays = new Display[] { createDefaultDisplay(), createExternalDisplay(), createOverlayDisplay()}; doReturn(mDisplays).when(mMockedInjector).getAllDisplays();