diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java index a7d92930b06..c73f847a7e3 100644 --- a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java @@ -29,10 +29,7 @@ import android.app.Activity; import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Bundle; -import android.os.SystemClock; -import android.view.Choreographer; import android.view.View; -import android.widget.SeekBar; import android.widget.TextView; import android.window.DesktopExperienceFlags; @@ -46,13 +43,10 @@ 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.DisplaySizeData; 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; -import com.android.settingslib.display.DisplayDensityUtils; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.IllustrationPreference; import com.android.settingslib.widget.MainSwitchPreference; @@ -352,38 +346,22 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen } @NonNull - private AccessibilitySeekBarPreference reuseSizePreference(Context context, - PrefRefresh refresh, int displayId, int position) { - AccessibilitySeekBarPreference pref = + private ExternalDisplaySizePreference reuseSizePreference(Context context, + PrefRefresh refresh, DisplayDevice display, int position) { + ExternalDisplaySizePreference pref = refresh.findUnusedPreference(PrefBasics.EXTERNAL_DISPLAY_SIZE.keyForNth(position)); 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); + pref = new ExternalDisplaySizePreference(context, /* attrs= */ null); PrefBasics.EXTERNAL_DISPLAY_SIZE.apply(pref, position); - - setStateForDisplaySizePreference(context, displayId, pref); + } + if (display.getMode() != null) { + pref.setStateForPreference(display.getMode().getPhysicalWidth(), + display.getMode().getPhysicalHeight(), display.getId()); } refresh.addPreference(pref); return pref; } - private void setStateForDisplaySizePreference(Context context, int displayId, - AccessibilitySeekBarPreference preference) { - var displaySizeData = new DisplaySizeData(context, - new DisplayDensityUtils(context, (info) -> info.displayId == displayId)); - ExternalDisplaySizePreferenceStateHandler seekBarChangeHandler = - new ExternalDisplaySizePreferenceStateHandler( - displaySizeData, preference); - - preference.setMax(displaySizeData.getValues().size() - 1); - preference.setProgress(displaySizeData.getInitialIndex()); - preference.setContinuousUpdates(false); - preference.setOnSeekBarChangeListener(seekBarChangeHandler); - } - private void update() { final var screen = getPreferenceScreen(); if (screen == null || mInjector == null || mInjector.getContext() == null) { @@ -587,7 +565,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen private void addSizePreference(final Context context, PrefRefresh refresh, DisplayDevice display, int position) { - var pref = reuseSizePreference(context, refresh, display.getId(), position); + var pref = reuseSizePreference(context, refresh, display, position); pref.setSummary(EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE); pref.setOnPreferenceClickListener( (Preference p) -> { @@ -637,54 +615,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen } } - private static class ExternalDisplaySizePreferenceStateHandler - implements SeekBar.OnSeekBarChangeListener { - private static final long MIN_COMMIT_INTERVAL_MS = 800; - private static final long CHANGE_BY_BUTTON_DELAY_MS = 300; - private final DisplaySizeData mDisplaySizeData; - private int mLastDisplayProgress; - private long mLastCommitTime; - private final AccessibilitySeekBarPreference mPreference; - ExternalDisplaySizePreferenceStateHandler(DisplaySizeData displaySizeData, - AccessibilitySeekBarPreference preference) { - mDisplaySizeData = displaySizeData; - mPreference = preference; - } - - final Choreographer.FrameCallback mCommit = this::tryCommitDisplaySizeConfig; - - private void tryCommitDisplaySizeConfig(long unusedFrameTimeNanos) { - final int displayProgress = mPreference.getProgress(); - if (displayProgress != mLastDisplayProgress) { - mDisplaySizeData.commit(displayProgress); - mLastDisplayProgress = displayProgress; - } - mLastCommitTime = SystemClock.elapsedRealtime(); - } - - private void postCommitDelayed() { - var commitDelayMs = CHANGE_BY_BUTTON_DELAY_MS; - if (SystemClock.elapsedRealtime() - mLastCommitTime < MIN_COMMIT_INTERVAL_MS) { - commitDelayMs += MIN_COMMIT_INTERVAL_MS; - } - - final Choreographer choreographer = Choreographer.getInstance(); - choreographer.removeFrameCallback(mCommit); - choreographer.postFrameCallbackDelayed(mCommit, commitDelayMs); - } - - @Override - public void onProgressChanged(@NonNull SeekBar seekBar, int i, boolean b) { - postCommitDelayed(); - } - - @Override - public void onStartTrackingTouch(@NonNull SeekBar seekBar) {} - - @Override - public void onStopTrackingTouch(@NonNull SeekBar seekBar) {} - } - private static class PrefRefresh implements AutoCloseable { private final PreferenceGroup mScreen; private final HashMap mUnusedPreferences = new HashMap<>(); diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplaySizePreference.java b/src/com/android/settings/connecteddevice/display/ExternalDisplaySizePreference.java new file mode 100644 index 00000000000..df405ba4a94 --- /dev/null +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplaySizePreference.java @@ -0,0 +1,124 @@ +/* + * Copyright 2025 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.connecteddevice.display; + +import android.content.Context; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.view.Choreographer; +import android.widget.SeekBar; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.settings.R; +import com.android.settings.accessibility.AccessibilitySeekBarPreference; +import com.android.settings.accessibility.DisplaySizeData; +import com.android.settingslib.display.DisplayDensityUtils; + +/** + * The display size preference setting used for External displays. + */ +public class ExternalDisplaySizePreference extends AccessibilitySeekBarPreference { + private int mDisplayWidth; + private int mDisplayHeight; + private int mDisplayId; + private Context mContext; + + public ExternalDisplaySizePreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + mContext = context; + mDisplayId = -1; + mDisplayWidth = 0; + mDisplayHeight = 0; + + setIconStart(R.drawable.ic_remove_24dp); + setIconStartContentDescription(R.string.screen_zoom_make_smaller_desc); + setIconEnd(R.drawable.ic_add_24dp); + setIconEndContentDescription(R.string.screen_zoom_make_larger_desc); + } + + /** Sets the display width and height for this preference. */ + public void setStateForPreference(int displayWidth, int displayHeight, int displayId) { + if (mDisplayWidth == displayWidth && mDisplayHeight == displayHeight + && displayId == mDisplayId) return; + mDisplayWidth = displayWidth; + mDisplayHeight = displayHeight; + mDisplayId = displayId; + + setStateForPreferenceInternal(); + } + + private void setStateForPreferenceInternal() { + var displaySizeData = new DisplaySizeData(mContext, + new DisplayDensityUtils(mContext, (info) -> info.displayId == mDisplayId)); + ExternalDisplaySizePreferenceStateHandler + seekBarChangeHandler = + new ExternalDisplaySizePreferenceStateHandler( + displaySizeData); + + setMax(displaySizeData.getValues().size() - 1); + setProgress(displaySizeData.getInitialIndex()); + setContinuousUpdates(false); + setOnSeekBarChangeListener(seekBarChangeHandler); + } + + private class ExternalDisplaySizePreferenceStateHandler + implements SeekBar.OnSeekBarChangeListener { + private static final long MIN_COMMIT_INTERVAL_MS = 800; + private static final long CHANGE_BY_BUTTON_DELAY_MS = 300; + private final DisplaySizeData mDisplaySizeData; + private int mLastDisplayProgress; + private long mLastCommitTime; + ExternalDisplaySizePreferenceStateHandler(DisplaySizeData displaySizeData) { + mDisplaySizeData = displaySizeData; + } + + final Choreographer.FrameCallback mCommit = this::tryCommitDisplaySizeConfig; + + private void tryCommitDisplaySizeConfig(long unusedFrameTimeNanos) { + final int displayProgress = getProgress(); + if (displayProgress != mLastDisplayProgress) { + mDisplaySizeData.commit(displayProgress); + mLastDisplayProgress = displayProgress; + } + mLastCommitTime = SystemClock.elapsedRealtime(); + } + + private void postCommitDelayed() { + var commitDelayMs = CHANGE_BY_BUTTON_DELAY_MS; + if (SystemClock.elapsedRealtime() - mLastCommitTime < MIN_COMMIT_INTERVAL_MS) { + commitDelayMs += MIN_COMMIT_INTERVAL_MS; + } + + final Choreographer choreographer = Choreographer.getInstance(); + choreographer.removeFrameCallback(mCommit); + choreographer.postFrameCallbackDelayed(mCommit, commitDelayMs); + } + + @Override + public void onProgressChanged(@NonNull SeekBar seekBar, int i, boolean b) { + postCommitDelayed(); + } + + @Override + public void onStartTrackingTouch(@NonNull SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(@NonNull SeekBar seekBar) {} + } +}