Loading src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java +9 −79 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) -> { Loading Loading @@ -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<String, Preference> mUnusedPreferences = new HashMap<>(); Loading src/com/android/settings/connecteddevice/display/ExternalDisplaySizePreference.java 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * 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) {} } } Loading
src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java +9 −79 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) -> { Loading Loading @@ -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<String, Preference> mUnusedPreferences = new HashMap<>(); Loading
src/com/android/settings/connecteddevice/display/ExternalDisplaySizePreference.java 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * 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) {} } }