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

Commit 2e0c1ffd authored by Matthew DeVore's avatar Matthew DeVore Committed by Android (Google) Code Review
Browse files

Merge "CD settings: clean up null handling" into main

parents 9f4a2a58 538dffe8
Loading
Loading
Loading
Loading
+87 −98
Original line number Diff line number Diff line
@@ -19,11 +19,6 @@ package com.android.settings.connecteddevice.display;
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.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 static com.android.settings.connecteddevice.display.ExternalDisplayUtilsKt.isDisplayInMiroringMode;

import android.app.Activity;
@@ -139,7 +134,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    private PreferenceCategory mBuiltinDisplayPreference;
    @Nullable
    private Preference mBuiltinDisplaySizeAndTextPreference;
    @Nullable
    @NonNull
    private ConnectedDisplayInjector mInjector;
    @Nullable
    private String[] mRotationEntries;
@@ -154,7 +149,9 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        }
    };

    public ExternalDisplayPreferenceFragment() {}
    public ExternalDisplayPreferenceFragment() {
        mInjector = new ConnectedDisplayInjector(/* context= */ null);
    }

    @VisibleForTesting
    ExternalDisplayPreferenceFragment(@NonNull ConnectedDisplayInjector injector) {
@@ -173,8 +170,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen

    @Override
    public void onCreateCallback(@Nullable Bundle icicle) {
        if (mInjector == null) {
            mInjector = new ConnectedDisplayInjector(getPrefContext());
        if (mInjector.getContext() == null) {
            mInjector = new ConnectedDisplayInjector(requireContext());
        }
        addPreferencesFromResource(EXTERNAL_DISPLAY_SETTINGS_RESOURCE);
    }
@@ -195,9 +192,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    @Override
    public void onStartCallback() {
        mStarted = true;
        if (mInjector == null) {
            return;
        }
        mInjector.registerDisplayListener(mListener);
        scheduleUpdate();
    }
@@ -205,9 +199,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    @Override
    public void onStopCallback() {
        mStarted = false;
        if (mInjector == null) {
            return;
        }
        mInjector.unregisterDisplayListener(mListener);
        unscheduleUpdate();
    }
@@ -221,10 +212,10 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @VisibleForTesting
    protected void launchResolutionSelector(@NonNull final Context context, final int displayId) {
    protected void launchResolutionSelector(final int displayId) {
        final Bundle args = new Bundle();
        args.putInt(DISPLAY_ID_ARG, displayId);
        new SubSettingLauncher(context)
        new SubSettingLauncher(requireContext())
                .setDestination(ResolutionPreferenceFragment.class.getName())
                .setArguments(args)
                .setSourceMetricsCategory(getMetricsCategory()).launch();
@@ -233,8 +224,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    @VisibleForTesting
    protected void launchBuiltinDisplaySettings() {
        final Bundle args = new Bundle();
        var context = getPrefContext();
        new SubSettingLauncher(context)
        new SubSettingLauncher(requireContext())
                .setDestination(TextReadingPreferenceFragment.class.getName())
                .setArguments(args)
                .setSourceMetricsCategory(getMetricsCategory()).launch();
@@ -242,17 +232,17 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen

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

    /**
     * Returns the preference for the footer.
     */
    private void addFooterPreference(Context context, PrefRefresh refresh, int title) {
    private void addFooterPreference(PrefRefresh refresh, int title) {
        var pref = refresh.findUnusedPreference(PrefBasics.FOOTER.key);
        if (pref == null) {
            pref = newFooterPreference(context);
            pref = newFooterPreference();
            PrefBasics.FOOTER.apply(pref, /* nth= */ null);
        }
        pref.setTitle(title);
@@ -260,12 +250,11 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @NonNull
    private ListPreference reuseRotationPreference(@NonNull Context context, PrefRefresh refresh,
            int position) {
    private ListPreference reuseRotationPreference(PrefRefresh refresh, int position) {
        ListPreference pref = refresh.findUnusedPreference(
                PrefBasics.EXTERNAL_DISPLAY_ROTATION.keyForNth(position));
        if (pref == null) {
            pref = new ListPreference(context);
            pref = new ListPreference(requireContext());
            PrefBasics.EXTERNAL_DISPLAY_ROTATION.apply(pref, position);
        }
        refresh.addPreference(pref);
@@ -273,12 +262,11 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @NonNull
    private Preference reuseResolutionPreference(@NonNull Context context, PrefRefresh refresh,
            int position) {
    private Preference reuseResolutionPreference(PrefRefresh refresh, int position) {
        var pref = refresh.findUnusedPreference(
                PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.keyForNth(position));
        if (pref == null) {
            pref = new Preference(context);
            pref = new Preference(requireContext());
            PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.apply(pref, position);
        }
        refresh.addPreference(pref);
@@ -286,12 +274,11 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @NonNull
    private MainSwitchPreference reuseUseDisplayPreference(
            Context context, PrefRefresh refresh, int position) {
    private MainSwitchPreference reuseUseDisplayPreference(PrefRefresh refresh, int position) {
        MainSwitchPreference pref = refresh.findUnusedPreference(
                PrefBasics.EXTERNAL_DISPLAY_USE.keyForNth(position));
        if (pref == null) {
            pref = new MainSwitchPreference(context);
            pref = new MainSwitchPreference(requireContext());
            PrefBasics.EXTERNAL_DISPLAY_USE.apply(pref, position);
        }
        refresh.addPreference(pref);
@@ -299,11 +286,10 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @NonNull
    private IllustrationPreference reuseIllustrationPreference(
            Context context, PrefRefresh refresh) {
    private IllustrationPreference reuseIllustrationPreference(PrefRefresh refresh) {
        IllustrationPreference pref = refresh.findUnusedPreference(PrefBasics.ILLUSTRATION.key);
        if (pref == null) {
            pref = new IllustrationPreference(context);
            pref = new IllustrationPreference(requireContext());
            PrefBasics.ILLUSTRATION.apply(pref, /* nth= */ null);
        }
        refresh.addPreference(pref);
@@ -311,18 +297,19 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @NonNull
    private PreferenceCategory getBuiltinDisplayListPreference(@NonNull Context context) {
    private PreferenceCategory getBuiltinDisplayListPreference() {
        if (mBuiltinDisplayPreference == null) {
            mBuiltinDisplayPreference = new PreferenceCategory(context);
            mBuiltinDisplayPreference = new PreferenceCategory(requireContext());
            PrefBasics.BUILTIN_DISPLAY_LIST.apply(mBuiltinDisplayPreference, /* nth= */ null);
        }
        return mBuiltinDisplayPreference;
    }

    @NonNull
    private Preference getBuiltinDisplaySizeAndTextPreference(@NonNull Context context) {
    private Preference getBuiltinDisplaySizeAndTextPreference() {
        if (mBuiltinDisplaySizeAndTextPreference == null) {
            mBuiltinDisplaySizeAndTextPreference = new BuiltinDisplaySizeAndTextPreference(context);
            mBuiltinDisplaySizeAndTextPreference = new BuiltinDisplaySizeAndTextPreference(
                    requireContext());
        }
        return mBuiltinDisplaySizeAndTextPreference;
    }
@@ -335,10 +322,10 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        return mDisplayTopologyPreference;
    }

    private void addMirrorPreference(Context context, PrefRefresh refresh) {
    private void addMirrorPreference(PrefRefresh refresh) {
        Preference pref = refresh.findUnusedPreference(PrefBasics.MIRROR.key);
        if (pref == null) {
            pref = new MirrorPreference(context,
            pref = new MirrorPreference(requireContext(),
                DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue());
            PrefBasics.MIRROR.apply(pref, /* nth= */ null);
        }
@@ -346,12 +333,12 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    @NonNull
    private ExternalDisplaySizePreference reuseSizePreference(Context context,
    private ExternalDisplaySizePreference reuseSizePreference(
            PrefRefresh refresh, DisplayDevice display, int position) {
        ExternalDisplaySizePreference pref =
                refresh.findUnusedPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.keyForNth(position));
        if (pref == null) {
            pref = new ExternalDisplaySizePreference(context, /* attrs= */ null);
            pref = new ExternalDisplaySizePreference(requireContext(), /* attrs= */ null);
            PrefBasics.EXTERNAL_DISPLAY_SIZE.apply(pref, position);
        }
        if (display.getMode() != null) {
@@ -364,21 +351,21 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen

    private void update() {
        final var screen = getPreferenceScreen();
        if (screen == null || mInjector == null || mInjector.getContext() == null) {
        if (screen == null || getContext() == null) {
            return;
        }
        try (var cleanableScreen = new PrefRefresh(screen)) {
            updateScreen(cleanableScreen, mInjector.getContext());
            updateScreen(cleanableScreen);
        }
    }

    private void updateScreen(final PrefRefresh screen, Context context) {
    private void updateScreen(final PrefRefresh screen) {
        final var displaysToShow = mInjector.getConnectedDisplays();

        if (displaysToShow.isEmpty()) {
            showTextWhenNoDisplaysToShow(screen, context, /* position= */ 0);
            showTextWhenNoDisplaysToShow(screen, /* position= */ 0);
        } else {
            showDisplaysList(displaysToShow, screen, context);
            showDisplaysList(displaysToShow, screen);
        }

        final Activity activity = getCurrentActivity();
@@ -387,16 +374,19 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        }
    }

    private void showTextWhenNoDisplaysToShow(@NonNull final PrefRefresh screen,
            @NonNull Context context, int position) {
        if (isUseDisplaySettingEnabled(mInjector)) {
            addUseDisplayPreferenceNoDisplaysFound(context, screen, position);
    private boolean isUseDisplaySettingEnabled() {
        return mInjector.getFlags().resolutionAndEnableConnectedDisplaySetting()
                && !mInjector.getFlags().displayTopologyPaneInDisplayList();
    }

    private void showTextWhenNoDisplaysToShow(@NonNull final PrefRefresh screen, int position) {
        if (isUseDisplaySettingEnabled()) {
            addUseDisplayPreferenceNoDisplaysFound(screen, position);
        }
        addFooterPreference(context, screen, EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE);
        addFooterPreference(screen, EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE);
    }

    private static PreferenceCategory reuseDisplayCategory(
            PrefRefresh screen, Context context, int position) {
    private PreferenceCategory reuseDisplayCategory(PrefRefresh screen, int position) {
        // The rest of the settings are in a category with the display name as the title.
        String categoryKey = PrefBasics.EXTERNAL_DISPLAY_LIST.keyForNth(position);
        var category = (PreferenceCategory) screen.findUnusedPreference(categoryKey);
@@ -404,7 +394,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        if (category != null) {
            screen.addPreference(category);
        } else {
            category = new PreferenceCategory(context);
            category = new PreferenceCategory(requireContext());
            screen.addPreference(category);
            PrefBasics.EXTERNAL_DISPLAY_LIST.apply(category, position);
            category.setOrder(PrefBasics.BUILTIN_DISPLAY_LIST.order + 1 + position);
@@ -414,18 +404,18 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
    }

    private void showDisplaySettings(DisplayDevice display, PrefRefresh refresh,
            Context context, boolean includeV1Helpers, int position) {
        if (isUseDisplaySettingEnabled(mInjector)) {
            addUseDisplayPreferenceForDisplay(context, refresh, display, position);
            boolean includeV1Helpers, int position) {
        if (isUseDisplaySettingEnabled()) {
            addUseDisplayPreferenceForDisplay(refresh, display, position);
        }
        final var displayRotation = getDisplayRotation(display.getId());
        if (includeV1Helpers && display.isEnabled() == DisplayIsEnabled.YES) {
            addIllustrationImage(context, refresh, displayRotation);
            addIllustrationImage(refresh, displayRotation);
        }

        addResolutionPreference(context, refresh, display, position);
        addRotationPreference(context, refresh, display, displayRotation, position);
        if (isResolutionSettingEnabled(mInjector)) {
        addResolutionPreference(refresh, display, position);
        addRotationPreference(refresh, display, displayRotation, position);
        if (mInjector.getFlags().resolutionAndEnableConnectedDisplaySetting()) {
            // 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
            // bottom of the screen, the external resolution setting must be below the built-in
@@ -438,57 +428,58 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            // place.
            if (includeV1Helpers && display.isEnabled() == DisplayIsEnabled.YES) {
                addFooterPreference(
                        context, refresh, EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE);
                        refresh, EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE);
            }
        }
        if (isDisplaySizeSettingEnabled(mInjector) && !isDisplayInMiroringMode(context)) {
            addSizePreference(context, refresh, display, position);
        if (mInjector.getFlags().displaySizeConnectedDisplaySetting()
                && !isDisplayInMiroringMode(requireContext())) {
            addSizePreference(refresh, display, position);
        }
    }

    private void maybeAddV2Components(Context context, PrefRefresh screen) {
        if (isTopologyPaneEnabled(mInjector)) {
    private void maybeAddV2Components(PrefRefresh screen) {
        if (mInjector.getFlags().displayTopologyPaneInDisplayList()) {
            screen.addPreference(getDisplayTopologyPreference());
            addMirrorPreference(context, screen);
            addMirrorPreference(screen);

            // If topology is shown, we also show a preference for the built-in display for
            // consistency with the topology.
            var builtinCategory = getBuiltinDisplayListPreference(context);
            var builtinCategory = getBuiltinDisplayListPreference();
            screen.addPreference(builtinCategory);
            builtinCategory.addPreference(getBuiltinDisplaySizeAndTextPreference(context));
            builtinCategory.addPreference(getBuiltinDisplaySizeAndTextPreference());
        }
    }

    private void showDisplaysList(@NonNull List<DisplayDevice> displaysToShow,
            @NonNull PrefRefresh screen, @NonNull Context context) {
        maybeAddV2Components(context, screen);
            @NonNull PrefRefresh screen) {
        maybeAddV2Components(screen);
        int position = 0;
        boolean includeV1Helpers = !isTopologyPaneEnabled(mInjector) && displaysToShow.size() <= 1;
        boolean includeV1Helpers = !mInjector.getFlags().displayTopologyPaneInDisplayList()
                && displaysToShow.size() <= 1;
        for (var display : displaysToShow) {
            var category = reuseDisplayCategory(screen, context, position);
            var category = reuseDisplayCategory(screen, position);
            category.setTitle(display.getName());

            try (var refresh = new PrefRefresh(category)) {
                // The category may have already been populated if it was retrieved from `screen`,
                // but we still need to update resolution and rotation items.
                showDisplaySettings(display, refresh, context, includeV1Helpers, position);
                showDisplaySettings(display, refresh, includeV1Helpers, position);
            }

            position++;
        }
    }

    private void addUseDisplayPreferenceNoDisplaysFound(Context context, PrefRefresh refresh,
            int position) {
        final var pref = reuseUseDisplayPreference(context, refresh, position);
    private void addUseDisplayPreferenceNoDisplaysFound(PrefRefresh refresh, int position) {
        final var pref = reuseUseDisplayPreference(refresh, position);
        pref.setChecked(false);
        pref.setEnabled(false);
        pref.setOnPreferenceChangeListener(null);
    }

    private void addUseDisplayPreferenceForDisplay(final Context context,
    private void addUseDisplayPreferenceForDisplay(
            PrefRefresh refresh, final DisplayDevice display, int position) {
        final var pref = reuseUseDisplayPreference(context, refresh, position);
        final var pref = reuseUseDisplayPreference(refresh, position);
        pref.setChecked(display.isEnabled() == DisplayIsEnabled.YES);
        pref.setEnabled(true);
        pref.setOnPreferenceChangeListener((p, newValue) -> {
@@ -509,9 +500,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        });
    }

    private void addIllustrationImage(final Context context, PrefRefresh refresh,
            final int displayRotation) {
        var pref = reuseIllustrationPreference(context, refresh);
    private void addIllustrationImage(PrefRefresh refresh, final int displayRotation) {
        var pref = reuseIllustrationPreference(refresh);
        if (displayRotation % 2 == 0) {
            pref.setLottieAnimationResId(EXTERNAL_DISPLAY_PORTRAIT_DRAWABLE);
        } else {
@@ -519,15 +509,15 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
        }
    }

    private void addRotationPreference(final Context context, PrefRefresh refresh,
    private void addRotationPreference(PrefRefresh refresh,
            final DisplayDevice display, final int displayRotation, int position) {
        var pref = reuseRotationPreference(context, refresh, position);
        var pref = reuseRotationPreference(refresh, position);
        if (mRotationEntries == null || mRotationEntriesValues == null) {
            mRotationEntries = new String[] {
                    context.getString(R.string.external_display_standard_rotation),
                    context.getString(R.string.external_display_rotation_90),
                    context.getString(R.string.external_display_rotation_180),
                    context.getString(R.string.external_display_rotation_270)};
                    requireContext().getString(R.string.external_display_standard_rotation),
                    requireContext().getString(R.string.external_display_rotation_90),
                    requireContext().getString(R.string.external_display_rotation_180),
                    requireContext().getString(R.string.external_display_rotation_270)};
            mRotationEntriesValues = new String[] {"0", "1", "2", "3"};
        }
        pref.setEntries(mRotationEntries);
@@ -545,26 +535,25 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
            return true;
        });
        pref.setEnabled(display.isEnabled() == DisplayIsEnabled.YES
                && isRotationSettingEnabled(mInjector));
                && mInjector.getFlags().rotationConnectedDisplaySetting());
    }

    private void addResolutionPreference(final Context context, PrefRefresh refresh,
    private void addResolutionPreference(PrefRefresh refresh,
            final DisplayDevice display, int position) {
        var pref = reuseResolutionPreference(context, refresh, position);
        var pref = reuseResolutionPreference(refresh, position);
        pref.setSummary(display.getMode().getPhysicalWidth() + " x "
                + display.getMode().getPhysicalHeight());
        pref.setOnPreferenceClickListener((Preference p) -> {
            writePreferenceClickMetric(p);
            launchResolutionSelector(context, display.getId());
            launchResolutionSelector(display.getId());
            return true;
        });
        pref.setEnabled(display.isEnabled() == DisplayIsEnabled.YES
                && isResolutionSettingEnabled(mInjector));
                && mInjector.getFlags().resolutionAndEnableConnectedDisplaySetting());
    }

    private void addSizePreference(final Context context, PrefRefresh refresh,
            DisplayDevice display, int position) {
        var pref = reuseSizePreference(context, refresh, display, position);
    private void addSizePreference(PrefRefresh refresh, DisplayDevice display, int position) {
        var pref = reuseSizePreference(refresh, display, position);
        pref.setSummary(EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE);
        pref.setOnPreferenceClickListener(
                (Preference p) -> {
+0 −22
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.settings.connecteddevice.display;
import android.hardware.display.DisplayManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.settings.R;
import com.android.settings.flags.FeatureFlags;
@@ -72,25 +71,4 @@ public class ExternalDisplaySettingsConfiguration {
                || desktopExperienceFlags.displayTopologyPaneInDisplayList();
        return result;
    }

    static boolean isTopologyPaneEnabled(@Nullable ConnectedDisplayInjector injector) {
        return injector != null && injector.getFlags().displayTopologyPaneInDisplayList();
    }

    static boolean isUseDisplaySettingEnabled(@Nullable ConnectedDisplayInjector injector) {
        return injector != null && injector.getFlags().resolutionAndEnableConnectedDisplaySetting()
                && !injector.getFlags().displayTopologyPaneInDisplayList();
    }

    static boolean isResolutionSettingEnabled(@Nullable ConnectedDisplayInjector injector) {
        return injector != null && injector.getFlags().resolutionAndEnableConnectedDisplaySetting();
    }

    static boolean isRotationSettingEnabled(@Nullable ConnectedDisplayInjector injector) {
        return injector != null && injector.getFlags().rotationConnectedDisplaySetting();
    }

    static boolean isDisplaySizeSettingEnabled(@Nullable ConnectedDisplayInjector injector) {
        return injector != null && injector.getFlags().displaySizeConnectedDisplaySetting();
    }
}
+8 −3
Original line number Diff line number Diff line
@@ -492,6 +492,11 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
            mLogger = mMockedMetricsLogger;
        }

        @Override
        public Context getContext() {
            return mContext;
        }

        @Override
        public PreferenceScreen getPreferenceScreen() {
            return mPreferenceScreen;
@@ -523,13 +528,13 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
        }

        @Override
        protected void launchResolutionSelector(@NonNull Context context, int displayId) {
        protected void launchResolutionSelector(int displayId) {
            mResolutionSelectorDisplayId = displayId;
        }

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

        @Override