Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c37fc8b8 authored by Matthew DeVore's avatar Matthew DeVore
Browse files

Use PrefRefresh for Preference caching

Refactor a couple of fields to use PrefRefresh for caching instead
instead of fields. This makes us construct PrefRefresh for display
categories, which we hadn't been doing before, and was causing
b/397466966. This also limits the tests' dependency on implementation.

We had been using fields for caching Preference objects, which doesn't
account for the same preference being needed for each display.
PrefRefresh is a more flexible mechanism for recycling View objects and
it largely makes the fields obsolete.

The reuse* methods (previously get*Preference) can actually be inlined
now that tests aren't calling into them, but to keep the diff easy to
review I left them as separate methods.

Because @NonNull doesn't actually do anything, and is considered the
default, I neglected to add them to new arguments, and deleted them from
lines I modified.

Flag: com.android.settings.flags.display_topology_pane_in_display_list
Test: ExternalDisplayPreferenceFragmentTest.java
Test: with fragment visible, plug-in and activate a new physical display with the Mirror prompt
Test: with topology disabled, verify footer is shown with and without a display attached
Bug: b/397466966
Bug: b/397591022
Change-Id: I16b3ae925ca3d9d79471fd5df00b571ae3fc696f
parent d171e3e1
Loading
Loading
Loading
Loading
+87 −95
Original line number Diff line number Diff line
@@ -22,11 +22,11 @@ import static com.android.settings.connecteddevice.display.ExternalDisplaySettin
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;
import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isTopologyPaneEnabled;
import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.isUseDisplaySettingEnabled;

import android.app.Activity;
import android.app.settings.SettingsEnums;
@@ -59,7 +59,6 @@ import com.android.settingslib.widget.TwoTargetPreference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;

/**
 * The Settings screen for External Displays configuration and connection management.
@@ -130,28 +129,17 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    static final String PREVIOUSLY_SHOWN_LIST_KEY = "mPreviouslyShownListOfDisplays";
    private boolean mStarted;
    @Nullable
    private MainSwitchPreference mUseDisplayPref;
    @Nullable
    private IllustrationPreference mImagePreference;
    @Nullable
    private Preference mResolutionPreference;
    @Nullable
    private ListPreference mRotationPref;
    @Nullable
    private FooterPreference mFooterPreference;
    @Nullable
    private Preference mDisplayTopologyPreference;
    @Nullable
    private Preference mMirrorPreference;
    @Nullable
    private PreferenceCategory mDisplaysPreference;
    @Nullable
    private PreferenceCategory mBuiltinDisplayPreference;
    @Nullable
    private Preference mBuiltinDisplaySizeAndTextPreference;
    @Nullable
    private Injector mInjector;
    @Nullable private AccessibilitySeekBarPreference mDisplaySizePreference;
    @Nullable
    private String[] mRotationEntries;
    @Nullable
@@ -270,47 +258,59 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
                .setSourceMetricsCategory(getMetricsCategory()).launch();
    }

    // The real FooterPreference requires a resource which is not available in unit tests.
    @VisibleForTesting
    Preference newFooterPreference(Context context) {
        return new FooterPreference(context);
    }

    /**
     * Returns the preference for the footer.
     */
    @NonNull
    @VisibleForTesting
    FooterPreference getFooterPreference(@NonNull Context context) {
        if (mFooterPreference == null) {
            mFooterPreference = new FooterPreference(context);
            mFooterPreference.setPersistent(false);
    private void addFooterPreference(Context context, PrefRefresh refresh, int title) {
        var pref = refresh.findUnusedPreference(PrefBasics.FOOTER.key);
        if (pref == null) {
            pref = newFooterPreference(context);
            PrefBasics.FOOTER.apply(pref);
        }
        return mFooterPreference;
        pref.setTitle(title);
        refresh.addPreference(pref);
    }

    @NonNull
    @VisibleForTesting
    ListPreference getRotationPreference(@NonNull Context context) {
        if (mRotationPref == null) {
            mRotationPref = new ListPreference(context);
            PrefBasics.EXTERNAL_DISPLAY_ROTATION.apply(mRotationPref);
        }
        return mRotationPref;
    private ListPreference reuseRotationPreference(@NonNull Context context, PrefRefresh refresh) {
        ListPreference pref = refresh.findUnusedPreference(
                PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        if (pref == null) {
            pref = new ListPreference(context);
            PrefBasics.EXTERNAL_DISPLAY_ROTATION.apply(pref);
        }
        refresh.addPreference(pref);
        return pref;
    }

    @NonNull
    @VisibleForTesting
    Preference getResolutionPreference(@NonNull Context context) {
        if (mResolutionPreference == null) {
            mResolutionPreference = new Preference(context);
            PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.apply(mResolutionPreference);
    private Preference reuseResolutionPreference(@NonNull Context context, PrefRefresh refresh) {
        var pref = refresh.findUnusedPreference(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key);
        if (pref == null) {
            pref = new Preference(context);
            PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.apply(pref);
        }
        return mResolutionPreference;
        refresh.addPreference(pref);
        return pref;
    }

    @NonNull
    @VisibleForTesting
    MainSwitchPreference getUseDisplayPreference(@NonNull Context context) {
        if (mUseDisplayPref == null) {
            mUseDisplayPref = new MainSwitchPreference(context);
            PrefBasics.EXTERNAL_DISPLAY_USE.apply(mUseDisplayPref);
        }
        return mUseDisplayPref;
    private MainSwitchPreference reuseUseDisplayPreference(
            @NonNull Context context, @NonNull PrefRefresh refresh) {
        MainSwitchPreference pref = refresh.findUnusedPreference(
                PrefBasics.EXTERNAL_DISPLAY_USE.key);
        if (pref == null) {
            pref = new MainSwitchPreference(context);
            PrefBasics.EXTERNAL_DISPLAY_USE.apply(pref);
        }
        refresh.addPreference(pref);
        return pref;
    }

    @NonNull
@@ -366,18 +366,20 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @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);
    private AccessibilitySeekBarPreference reuseSizePreference(Context context,
            PrefRefresh refresh) {
        AccessibilitySeekBarPreference pref =
                refresh.findUnusedPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        if (pref == null) {
            pref = new AccessibilitySeekBarPreference(context, /* attrs= */ null);
            pref.setIconStart(R.drawable.ic_remove_24dp);
            pref.setIconStartContentDescription(R.string.screen_zoom_make_smaller_desc);
            pref.setIconEnd(R.drawable.ic_add_24dp);
            pref.setIconEndContentDescription(R.string.screen_zoom_make_larger_desc);
            PrefBasics.EXTERNAL_DISPLAY_SIZE.apply(pref);
        }
        return mDisplaySizePreference;
        refresh.addPreference(pref);
        return pref;
    }

    private void restoreState(@Nullable Bundle savedInstanceState) {
@@ -439,10 +441,9 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    private void showTextWhenNoDisplaysToShow(@NonNull final PrefRefresh screen,
            @NonNull Context context) {
        if (isUseDisplaySettingEnabled(mInjector)) {
            screen.addPreference(updateUseDisplayPreferenceNoDisplaysFound(context));
            addUseDisplayPreferenceNoDisplaysFound(context, screen);
        }
        screen.addPreference(updateFooterPreference(context,
                EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE));
        addFooterPreference(context, screen, EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE);
    }

    private static PreferenceCategory getCategoryForDisplay(@NonNull Display display,
@@ -469,7 +470,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            @NonNull Context context) {
        final var isEnabled = mInjector != null && mInjector.isDisplayEnabled(display);
        if (isUseDisplaySettingEnabled(mInjector)) {
            screen.addPreference(updateUseDisplayPreference(context, display, isEnabled));
            addUseDisplayPreferenceForDisplay(context, screen, display, isEnabled);
        }
        if (!isEnabled) {
            // Skip all other settings
@@ -480,17 +481,21 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            screen.addPreference(updateIllustrationImage(context, displayRotation));
        }

        Consumer<Preference> adder;
        if (isTopologyPaneEnabled(mInjector)) {
            adder = getCategoryForDisplay(display, screen, context)::addPreference;
            // The category may have already been populated if it was retrieved from the PrefRefresh
            // backup, but we still need to update resolution and rotation items.
            var displayCategory = getCategoryForDisplay(display, screen, context);
            try (var categoryRefresh = new PrefRefresh(displayCategory)) {
                addDisplaySettings(context, categoryRefresh, display, displayRotation);
            }
        } else {
            adder = screen::addPreference;
            addDisplaySettings(context, screen, display, displayRotation);
        }

        adder.accept(updateResolutionPreference(context, display));
        adder.accept(updateRotationPreference(context, display, displayRotation));
    }

    private void addDisplaySettings(Context context, PrefRefresh refresh, Display display,
            int displayRotation) {
        addResolutionPreference(context, refresh, display);
        addRotationPreference(context, refresh, display, displayRotation);
        if (isResolutionSettingEnabled(mInjector)) {
            // Do not show the footer about changing resolution affecting apps. This is not in the
            // UX design for v2, and there is no good place to put it, since (a) if it is on the
@@ -503,12 +508,12 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            // TODO(b/352648432): probably remove footer once the pane and rest of v2 UI is in
            // place.
            if (!isTopologyPaneEnabled(mInjector)) {
                adder.accept(updateFooterPreference(context,
                        EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE));
                addFooterPreference(
                        context, refresh, EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE);
            }
        }
        if (isDisplaySizeSettingEnabled(mInjector)) {
            adder.accept(updateSizePreference(context));
            addSizePreference(context, refresh);
        }
    }

@@ -597,17 +602,16 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        return displaysToShow;
    }

    private Preference updateUseDisplayPreferenceNoDisplaysFound(@NonNull Context context) {
        final var pref = getUseDisplayPreference(context);
    private void addUseDisplayPreferenceNoDisplaysFound(Context context, PrefRefresh refresh) {
        final var pref = reuseUseDisplayPreference(context, refresh);
        pref.setChecked(false);
        pref.setEnabled(false);
        pref.setOnPreferenceChangeListener(null);
        return pref;
    }

    private Preference updateUseDisplayPreference(@NonNull final Context context,
            @NonNull final Display display, boolean isEnabled) {
        final var pref = getUseDisplayPreference(context);
    private void addUseDisplayPreferenceForDisplay(final Context context,
            PrefRefresh refresh, final Display display, boolean isEnabled) {
        final var pref = reuseUseDisplayPreference(context, refresh);
        pref.setChecked(isEnabled);
        pref.setEnabled(true);
        pref.setOnPreferenceChangeListener((p, newValue) -> {
@@ -626,7 +630,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            }
            return result;
        });
        return pref;
    }

    private Preference updateIllustrationImage(@NonNull final Context context,
@@ -640,16 +643,9 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        return pref;
    }

    private Preference updateFooterPreference(@NonNull final Context context, final int title) {
        var pref = getFooterPreference(context);
        pref.setTitle(title);
        PrefBasics.FOOTER.apply(pref);
        return pref;
    }

    private Preference updateRotationPreference(@NonNull final Context context,
            @NonNull final Display display, final int displayRotation) {
        var pref = getRotationPreference(context);
    private void addRotationPreference(final Context context,
            PrefRefresh refresh, final Display display, final int displayRotation) {
        var pref = reuseRotationPreference(context, refresh);
        if (mRotationEntries == null || mRotationEntriesValues == null) {
            mRotationEntries = new String[] {
                    context.getString(R.string.external_display_standard_rotation),
@@ -673,12 +669,11 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            return true;
        });
        pref.setEnabled(isRotationSettingEnabled(mInjector));
        return pref;
    }

    private Preference updateResolutionPreference(@NonNull final Context context,
            @NonNull final Display display) {
        var pref = getResolutionPreference(context);
    private void addResolutionPreference(final Context context, PrefRefresh refresh,
            final Display display) {
        var pref = reuseResolutionPreference(context, refresh);
        pref.setSummary(display.getMode().getPhysicalWidth() + " x "
                + display.getMode().getPhysicalHeight());
        pref.setOnPreferenceClickListener((Preference p) -> {
@@ -687,19 +682,16 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            return true;
        });
        pref.setEnabled(isResolutionSettingEnabled(mInjector));
        return pref;
    }

    private Preference updateSizePreference(@NonNull final Context context) {
        var pref = (Preference) getSizePreference(context);
        PrefBasics.EXTERNAL_DISPLAY_SIZE.apply(pref);
    private void addSizePreference(final Context context, PrefRefresh refresh) {
        var pref = reuseSizePreference(context, refresh);
        pref.setSummary(EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE);
        pref.setOnPreferenceClickListener(
                (Preference p) -> {
                    writePreferenceClickMetric(p);
                    return true;
                });
        return pref;
    }

    private int getDisplayRotation(int displayId) {
@@ -779,8 +771,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        }

        @Nullable
        Preference findUnusedPreference(@NonNull String key) {
            return mUnusedPreferences.get(key);
        <P extends Preference> P findUnusedPreference(@NonNull String key) {
            return (P) mUnusedPreferences.get(key);
        }

        boolean addPreference(@NonNull final Preference pref) {
+25 −24
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import static com.android.settings.connecteddevice.display.ExternalDisplayPrefer
import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.resolutionRotationPreferenceKey;
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;

import static com.google.common.truth.Truth.assertThat;

@@ -47,6 +46,7 @@ import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
@@ -55,7 +55,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.DisplayPreference;
import com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.PrefBasics;
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.MainSwitchPreference;

import org.junit.Test;
@@ -237,11 +236,12 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        assertThat(pref).isNotNull();
        pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        assertThat(pref).isNotNull();
        var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER);
        var footerPref = mPreferenceScreen.findPreference(PrefBasics.FOOTER.key);
        assertThat(footerPref).isNotNull();
        var sizePref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        assertThat(sizePref).isNull();
        verify(footerPref).setTitle(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE);
        assertThat("" + footerPref.getTitle())
                .isEqualTo(getText(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE));
    }

    @Test
@@ -259,11 +259,12 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        assertThat(pref).isNotNull();
        pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        assertThat(pref).isNotNull();
        var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER);
        var footerPref = mPreferenceScreen.findPreference(PrefBasics.FOOTER.key);
        assertThat(footerPref).isNotNull();
        var sizePref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        assertThat(sizePref).isNotNull();
        verify(footerPref).setTitle(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE);
        assertThat("" + footerPref.getTitle())
                .isEqualTo(getText(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE));
    }

    @Test
@@ -279,11 +280,12 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        assertThat(pref).isNotNull();
        pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        assertThat(pref).isNotNull();
        var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER);
        var footerPref = mPreferenceScreen.findPreference(PrefBasics.FOOTER.key);
        assertThat(footerPref).isNotNull();
        var sizePref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        assertThat(sizePref).isNotNull();
        verify(footerPref).setTitle(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE);
        assertThat("" + footerPref.getTitle())
                .isEqualTo(getText(EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE));
    }

    @Test
@@ -306,7 +308,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        assertThat(pref).isNull();
        pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        assertThat(pref).isNull();
        var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER);
        var footerPref = mPreferenceScreen.findPreference(PrefBasics.FOOTER.key);
        assertThat(footerPref).isNull();
        var sizePref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        assertThat(sizePref).isNull();
@@ -326,9 +328,10 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        assertThat(mainPref.isChecked()).isFalse();
        assertThat(mainPref.isEnabled()).isFalse();
        assertThat(mainPref.getOnPreferenceChangeListener()).isNull();
        var footerPref = (FooterPreference) mPreferenceScreen.findPreference(KEY_FOOTER);
        var footerPref = mPreferenceScreen.findPreference(PrefBasics.FOOTER.key);
        assertThat(footerPref).isNotNull();
        verify(footerPref).setTitle(EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE);
        assertThat("" + footerPref.getTitle())
                .isEqualTo(getText(EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE));
    }

    @Test
@@ -338,7 +341,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        doReturn(true).when(mMockedInjector).isDisplayEnabled(any());
        var fragment = initFragment();
        mHandler.flush();
        var pref = fragment.getRotationPreference(mContext);
        ListPreference pref =
                mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        assertThat(pref.getKey()).isEqualTo(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key);
        assertThat("" + pref.getTitle()).isEqualTo(
                getText(PrefBasics.EXTERNAL_DISPLAY_ROTATION.titleResource));
@@ -370,7 +374,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        doReturn(true).when(mMockedInjector).isDisplayEnabled(any());
        var fragment = initFragment();
        mHandler.flush();
        var pref = fragment.getResolutionPreference(mContext);
        var pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key);
        assertThat(pref.getKey()).isEqualTo(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key);
        assertThat("" + pref.getTitle()).isEqualTo(
                getText(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.titleResource));
@@ -389,7 +393,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        doReturn(true).when(mMockedInjector).isDisplayEnabled(any());
        var fragment = initFragment();
        mHandler.flush();
        var pref = fragment.getSizePreference(mContext);
        var pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        assertThat(pref.getKey()).isEqualTo(PrefBasics.EXTERNAL_DISPLAY_SIZE.key);
        assertThat("" + pref.getTitle())
                .isEqualTo(getText(PrefBasics.EXTERNAL_DISPLAY_SIZE.titleResource));
@@ -410,7 +414,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        doReturn(true).when(mMockedInjector).disableConnectedDisplay(mDisplayIdArg);
        var fragment = initFragment();
        mHandler.flush();
        var pref = fragment.getUseDisplayPreference(mContext);
        MainSwitchPreference pref =
                mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_USE.key);
        assertThat(pref.getKey()).isEqualTo(PrefBasics.EXTERNAL_DISPLAY_USE.key);
        assertThat("" + pref.getTitle())
                .isEqualTo(getText(PrefBasics.EXTERNAL_DISPLAY_USE.titleResource));
@@ -455,15 +460,12 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        private final View mMockedRootView;
        private final TextView mEmptyView;
        private final Activity mMockedActivity;
        private final FooterPreference mMockedFooterPreference;
        private final MetricsLogger mLogger;

        TestableExternalDisplayPreferenceFragment() {
            super(mMockedInjector);
            mMockedActivity = mock(Activity.class);
            mMockedRootView = mock(View.class);
            mMockedFooterPreference = mock(FooterPreference.class);
            doReturn(KEY_FOOTER).when(mMockedFooterPreference).getKey();
            mEmptyView = new TextView(mContext);
            doReturn(mEmptyView).when(mMockedRootView).findViewById(android.R.id.empty);
            mLogger = mMockedMetricsLogger;
@@ -499,12 +501,6 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
            mPreferenceIdFromResource = resource;
        }

        @Override
        @NonNull
        FooterPreference getFooterPreference(@NonNull Context context) {
            return mMockedFooterPreference;
        }

        @Override
        protected int getDisplayIdArg() {
            return mDisplayIdArg;
@@ -520,6 +516,11 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
            mDisplayIdArg = displayId;
        }

        @Override
        Preference newFooterPreference(Context context) {
            return new Preference(context);
        }

        @Override
        protected void launchBuiltinDisplaySettings() {
            mLaunchedBuiltinSettings = true;