From 4a3af3a735a15743d338b670fb8c6760d02b68ef Mon Sep 17 00:00:00 2001 From: Matthew DeVore Date: Tue, 26 Nov 2024 00:31:22 +0000 Subject: [PATCH] Show built-in display if topology is visible The topology in the External Displays list will include the built-in display. For consistency, also show the built-in display along with the connected displays, so there is a 1:1 correspondence between blocks in the topology pane and display preference items. Test: launch external display fragment with zero or one external display, verify built-in display item appears and opens Display settings if tapped Flag: com.android.settings.flags.display_topology_pane_in_display_list Bug: b/352648432 Change-Id: Id067034f6af5d0d6fe32f4a8091bc77d1ed75698 --- res/values/strings.xml | 2 + .../ExternalDisplayPreferenceFragment.java | 66 +++++++++++++++++-- ...ExternalDisplayPreferenceFragmentTest.java | 28 +++++++- 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4d51512d29f..099056e0fa1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2005,6 +2005,8 @@ Off External Display + + Built-in display Use external display diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java index 047ffd41da2..de1363d24cd 100644 --- a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java @@ -16,7 +16,6 @@ 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; @@ -46,6 +45,7 @@ import androidx.preference.PreferenceScreen; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragmentBase; +import com.android.settings.accessibility.TextReadingPreferenceFragment; import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.DisplayListener; import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.Injector; import com.android.settings.core.SubSettingLauncher; @@ -64,6 +64,7 @@ import java.util.List; public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmentBase { static final int EXTERNAL_DISPLAY_SETTINGS_RESOURCE = R.xml.external_display_settings; static final String DISPLAYS_LIST_PREFERENCE_KEY = "displays_list_preference"; + static final String BUILTIN_DISPLAY_LIST_PREFERENCE_KEY = "builtin_display_list_preference"; 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"; @@ -83,6 +84,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 BUILTIN_DISPLAY_SETTINGS_CATEGORY_RESOURCE = + R.string.builtin_display_settings_category; @VisibleForTesting static final String PREVIOUSLY_SHOWN_LIST_KEY = "mPreviouslyShownListOfDisplays"; private boolean mStarted; @@ -101,6 +104,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen @Nullable private PreferenceCategory mDisplaysPreference; @Nullable + private PreferenceCategory mBuiltinDisplayPreference; + @Nullable private Injector mInjector; @Nullable private String[] mRotationEntries; @@ -200,7 +205,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen } @VisibleForTesting - protected void launchDisplaySettings(final int displayId) { + protected void launchExternalDisplaySettings(final int displayId) { final Bundle args = new Bundle(); var context = getPrefContext(); args.putInt(DISPLAY_ID_ARG, displayId); @@ -210,6 +215,16 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen .setSourceMetricsCategory(getMetricsCategory()).launch(); } + @VisibleForTesting + protected void launchBuiltinDisplaySettings() { + final Bundle args = new Bundle(); + var context = getPrefContext(); + new SubSettingLauncher(context) + .setDestination(TextReadingPreferenceFragment.class.getName()) + .setArguments(args) + .setSourceMetricsCategory(getMetricsCategory()).launch(); + } + /** * Returns the preference for the footer. */ @@ -281,6 +296,15 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen return mDisplaysPreference; } + @NonNull + private PreferenceCategory getBuiltinDisplayListPreference(@NonNull Context context) { + if (mBuiltinDisplayPreference == null) { + mBuiltinDisplayPreference = new PreferenceCategory(context); + mBuiltinDisplayPreference.setPersistent(false); + } + return mBuiltinDisplayPreference; + } + @NonNull Preference getDisplayTopologyPreference(@NonNull Context context) { if (mDisplayTopologyPreference == null) { mDisplayTopologyPreference = new DisplayTopologyPreference(context); @@ -310,7 +334,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen @NonNull final PreferenceScreen screen, @NonNull Context context) { final boolean forceShowList = displayId == INVALID_DISPLAY && mInjector != null && forceShowDisplayList(mInjector.getFlags()); - final var displaysToShow = getDisplaysToShow(displayId); + final var displaysToShow = externalDisplaysToShow(displayId); if (!forceShowList && displaysToShow.isEmpty() && displayId == INVALID_DISPLAY) { showTextWhenNoDisplaysToShow(screen, context); @@ -373,9 +397,18 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen private void showDisplaysList(@NonNull List displaysToShow, @NonNull PreferenceScreen screen, @NonNull Context context) { - if (mInjector != null - && mInjector.getFlags().displayTopologyPaneInDisplayList()) { + if (mInjector != null && mInjector.getFlags().displayTopologyPaneInDisplayList()) { screen.addPreference(getDisplayTopologyPreference(context)); + + // If topology is shown, we also show a preference for the built-in display for + // consistency with the topology. + var builtinCategory = getBuiltinDisplayListPreference(context); + builtinCategory.setKey(BUILTIN_DISPLAY_LIST_PREFERENCE_KEY); + builtinCategory.setTitle(BUILTIN_DISPLAY_SETTINGS_CATEGORY_RESOURCE); + builtinCategory.removeAll(); + screen.addPreference(builtinCategory); + + builtinCategory.addPreference(new BuiltinDisplaySizeAndTextPreference(context)); } var pref = getDisplaysListPreference(context); @@ -389,7 +422,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen } } - private List getDisplaysToShow(int displayIdToShow) { + private List externalDisplaysToShow(int displayIdToShow) { if (mInjector == null) { return List.of(); } @@ -530,6 +563,24 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen mInjector.getHandler().removeCallbacks(mUpdateRunnable); } + private class BuiltinDisplaySizeAndTextPreference extends Preference + implements Preference.OnPreferenceClickListener { + BuiltinDisplaySizeAndTextPreference(@NonNull final Context context) { + super(context); + + setPersistent(false); + setKey("builtin_display_size_and_text"); + setTitle(R.string.accessibility_text_reading_options_title); + setOnPreferenceClickListener(this); + } + + @Override + public boolean onPreferenceClick(@NonNull Preference preference) { + launchBuiltinDisplaySettings(); + return true; + } + } + @VisibleForTesting class DisplayPreference extends TwoTargetPreference implements Preference.OnPreferenceClickListener { @@ -538,6 +589,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen DisplayPreference(@NonNull final Context context, @NonNull final Display display) { super(context); mDisplayId = display.getDisplayId(); + setPersistent(false); setKey("display_id_" + mDisplayId); setTitle(display.getName()); @@ -548,7 +600,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen @Override public boolean onPreferenceClick(@NonNull Preference preference) { - launchDisplaySettings(mDisplayId); + launchExternalDisplaySettings(mDisplayId); writePreferenceClickMetric(preference); return true; } 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 63652260296..93ba97b27f5 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java @@ -71,6 +71,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa private ExternalDisplayPreferenceFragment mFragment; private int mPreferenceIdFromResource; private int mDisplayIdArg = INVALID_DISPLAY; + private boolean mLaunchedBuiltinSettings; private int mResolutionSelectorDisplayId = INVALID_DISPLAY; @Mock private MetricsLogger mMockedMetricsLogger; @@ -106,6 +107,10 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa pref = mPreferenceScreen.findPreference(DisplayTopologyKt.PREFERENCE_KEY); assertThat(pref).isNull(); + + pref = mPreferenceScreen.findPreference( + ExternalDisplayPreferenceFragment.BUILTIN_DISPLAY_LIST_PREFERENCE_KEY); + assertThat(pref).isNull(); } @Test @@ -124,6 +129,11 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY); assertThat(listPref).isNotNull(); assertThat(listPref.getPreferenceCount()).isEqualTo(1); + + listPref = mPreferenceScreen.findPreference( + ExternalDisplayPreferenceFragment.BUILTIN_DISPLAY_LIST_PREFERENCE_KEY); + assertThat(listPref).isNotNull(); + assertThat(listPref.getPreferenceCount()).isEqualTo(1); } @Test @@ -138,11 +148,18 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa var pref = mPreferenceScreen.findPreference(DisplayTopologyKt.PREFERENCE_KEY); assertThat(pref).isNotNull(); - // TODO: add the built-in display to the list, which will cause this preference to not be - // null. PreferenceCategory listPref = mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY); assertThat(listPref).isNull(); + + listPref = mPreferenceScreen.findPreference( + ExternalDisplayPreferenceFragment.BUILTIN_DISPLAY_LIST_PREFERENCE_KEY); + assertThat(listPref).isNotNull(); + assertThat(listPref.getPreferenceCount()).isEqualTo(1); + var builtinPref = listPref.getPreference(0); + assertThat(builtinPref.getOnPreferenceClickListener().onPreferenceClick(builtinPref)) + .isTrue(); + assertThat(mLaunchedBuiltinSettings).isTrue(); } @Test @@ -428,10 +445,15 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa } @Override - protected void launchDisplaySettings(final int displayId) { + protected void launchExternalDisplaySettings(final int displayId) { mDisplayIdArg = displayId; } + @Override + protected void launchBuiltinDisplaySettings() { + mLaunchedBuiltinSettings = true; + } + @Override protected void writePreferenceClickMetric(Preference preference) { mLogger.writePreferenceClickMetric(preference);