Loading services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +9 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,10 @@ public class DisplayManagerFlags { com.android.graphics.surfaceflinger.flags.Flags.FLAG_ENABLE_SMALL_AREA_DETECTION, com.android.graphics.surfaceflinger.flags.Flags::enableSmallAreaDetection); private final FlagState mDisplayConfigErrorHalFlagState = new FlagState( com.android.graphics.surfaceflinger.flags.Flags.FLAG_DISPLAY_CONFIG_ERROR_HAL, com.android.graphics.surfaceflinger.flags.Flags::displayConfigErrorHal); private final FlagState mBrightnessIntRangeUserPerceptionFlagState = new FlagState( Flags.FLAG_BRIGHTNESS_INT_RANGE_USER_PERCEPTION, Flags::brightnessIntRangeUserPerception); Loading Loading @@ -361,6 +365,10 @@ public class DisplayManagerFlags { return mSmallAreaDetectionFlagState.isEnabled(); } public boolean isDisplayConfigErrorHalEnabled() { return mDisplayConfigErrorHalFlagState.isEnabled(); } public boolean isBrightnessIntRangeUserPerceptionEnabled() { return mBrightnessIntRangeUserPerceptionFlagState.isEnabled(); } Loading Loading @@ -591,6 +599,7 @@ public class DisplayManagerFlags { pw.println(" " + mPowerThrottlingClamperFlagState); pw.println(" " + mEvenDimmerFlagState); pw.println(" " + mSmallAreaDetectionFlagState); pw.println(" " + mDisplayConfigErrorHalFlagState); pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState); pw.println(" " + mRestrictDisplayModes); pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState); Loading services/core/java/com/android/server/display/mode/DisplayModeDirector.java +5 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,7 @@ public class DisplayModeDirector { private final ProximitySensorObserver mSensorObserver; private final HbmObserver mHbmObserver; private final SkinThermalStatusObserver mSkinThermalStatusObserver; private final ModeChangeObserver mModeChangeObserver; @Nullable private final SystemRequestObserver mSystemRequestObserver; Loading Loading @@ -247,6 +248,7 @@ public class DisplayModeDirector { mDisplayObserver = new DisplayObserver(context, handler, mVotesStorage, injector); mSensorObserver = new ProximitySensorObserver(mVotesStorage, injector); mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, mVotesStorage); mModeChangeObserver = new ModeChangeObserver(mVotesStorage, injector, handler.getLooper()); mHbmObserver = new HbmObserver(injector, mVotesStorage, BackgroundThread.getHandler(), mDeviceConfigDisplaySettings); if (displayManagerFlags.isRestrictDisplayModesEnabled()) { Loading Loading @@ -275,6 +277,9 @@ public class DisplayModeDirector { mSensorObserver.observe(); mHbmObserver.observe(); mSkinThermalStatusObserver.observe(); if (mDisplayManagerFlags.isDisplayConfigErrorHalEnabled()) { mModeChangeObserver.observe(); } synchronized (mLock) { // We may have a listener already registered before the call to start, so go ahead and // notify them to pick up our newly initialized state. Loading services/core/java/com/android/server/display/mode/ModeChangeObserver.java 0 → 100644 +108 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.display.mode; import android.os.Looper; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayAddress; import android.view.DisplayEventReceiver; import com.android.internal.annotations.KeepForWeakReference; import java.util.HashSet; import java.util.Set; final class ModeChangeObserver { private static final String TAG = "ModeChangeObserver"; private final VotesStorage mVotesStorage; private final DisplayModeDirector.Injector mInjector; @SuppressWarnings("unused") @KeepForWeakReference private DisplayEventReceiver mModeChangeListener; private final SparseArray<Set<Integer>> mRejectedModesByDisplay = new SparseArray<>(); private Looper mLooper; ModeChangeObserver(VotesStorage votesStorage, DisplayModeDirector.Injector injector, Looper looper) { mVotesStorage = votesStorage; mInjector = injector; mLooper = looper; } void observe() { mModeChangeListener = new DisplayEventReceiver(mLooper) { @Override public void onModeRejected(long physicalDisplayId, int modeId) { Slog.d(TAG, "Mode Rejected event received"); int displayId = getLogicalDisplayId(physicalDisplayId); if (displayId < 0) { Slog.e(TAG, "Logical Display Id not found"); return; } populateRejectedModesListByDisplay(displayId, modeId); } @Override public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { Slog.d(TAG, "Hotplug event received"); if (!connected) { int displayId = getLogicalDisplayId(physicalDisplayId); if (displayId < 0) { Slog.e(TAG, "Logical Display Id not found"); return; } clearRejectedModesListByDisplay(displayId); } } }; } private int getLogicalDisplayId(long rejectedModePhysicalDisplayId) { Display[] displays = mInjector.getDisplays(); for (Display display : displays) { DisplayAddress address = display.getAddress(); if (address instanceof DisplayAddress.Physical physical) { long physicalDisplayId = physical.getPhysicalDisplayId(); if (physicalDisplayId == rejectedModePhysicalDisplayId) { return display.getDisplayId(); } } } return -1; } private void populateRejectedModesListByDisplay(int displayId, int rejectedModeId) { Set<Integer> alreadyRejectedModes = mRejectedModesByDisplay.get(displayId); if (alreadyRejectedModes == null) { alreadyRejectedModes = new HashSet<>(); mRejectedModesByDisplay.put(displayId, alreadyRejectedModes); } alreadyRejectedModes.add(rejectedModeId); mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, Vote.forRejectedModes(alreadyRejectedModes)); } private void clearRejectedModesListByDisplay(int displayId) { mRejectedModesByDisplay.remove(displayId); mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, null); } } services/core/java/com/android/server/display/mode/RejectedModesVote.java 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.display.mode; import android.annotation.NonNull; import java.util.Collections; import java.util.Set; public class RejectedModesVote implements Vote { final Set<Integer> mModeIds; RejectedModesVote(Set<Integer> modeIds) { mModeIds = Collections.unmodifiableSet(modeIds); } @Override public void updateSummary(@NonNull VoteSummary summary) { summary.rejectedModeIds.addAll(mModeIds); } @Override public String toString() { return "RejectedModesVote{ mModeIds=" + mModeIds + " }"; } } services/core/java/com/android/server/display/mode/Vote.java +28 −15 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Set; interface Vote { // DEFAULT_RENDER_FRAME_RATE votes for render frame rate [0, DEFAULT]. As the lowest Loading Loading @@ -82,68 +83,73 @@ interface Vote { int PRIORITY_APP_REQUEST_SIZE = 7; // PRIORITY_REJECTED_MODES rejects the modes for which the mode config failed // so that the modeset can be retried for next available mode after filtering // out the rejected modes for the connected display int PRIORITY_REJECTED_MODES = 8; // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE restricts physical refresh rate to // [0, max(PEAK, MIN)], depending on user settings peakRR/minRR values int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 8; int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 9; // PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE has a higher priority than // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE and will limit render rate to [0, max(PEAK, MIN)] // in case physical refresh rate vote is discarded (due to other high priority votes), // render rate vote can still apply int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 9; int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 10; // Restrict all displays physical refresh rate to 60Hz when external display is connected. // It votes [59Hz, 61Hz]. int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 10; int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 11; // PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE has a higher priority than // PRIORITY_SYNCHRONIZED_REFRESH_RATE and will limit render rate to [59Hz, 61Hz]. // In case physical refresh rate vote discarded (due to physical refresh rate not supported), // render rate vote can still apply. int PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE = 11; int PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE = 12; // Restrict displays max available resolution and refresh rates. It votes [0, LIMIT] int PRIORITY_LIMIT_MODE = 12; int PRIORITY_LIMIT_MODE = 13; // To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh // rate to max value (same as for PRIORITY_UDFPS) on lock screen int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 13; int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 14; // For concurrent displays we want to limit refresh rate on all displays int PRIORITY_LAYOUT_LIMITED_REFRESH_RATE = 14; int PRIORITY_LAYOUT_LIMITED_REFRESH_RATE = 15; // For concurrent displays we want to limit refresh rate on all displays int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 15; int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 16; // For internal application to limit display modes to specific ids int PRIORITY_SYSTEM_REQUESTED_MODES = 16; int PRIORITY_SYSTEM_REQUESTED_MODES = 17; // PRIORITY_LOW_POWER_MODE_MODES limits display modes to specific refreshRate-vsync pairs if // Settings.Global.LOW_POWER_MODE is on. // Lower priority that PRIORITY_LOW_POWER_MODE_RENDER_RATE and if discarded (due to other // higher priority votes), render rate limit can still apply int PRIORITY_LOW_POWER_MODE_MODES = 17; int PRIORITY_LOW_POWER_MODE_MODES = 18; // PRIORITY_LOW_POWER_MODE_RENDER_RATE force the render frame rate to [0, 60HZ] if // Settings.Global.LOW_POWER_MODE is on. int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 18; int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 19; // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the // higher priority voters' result is a range, it will fix the rate to a single choice. // It's used to avoid refresh rate switches in certain conditions which may result in the // user seeing the display flickering when the switches occur. int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 19; int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 20; // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL. int PRIORITY_SKIN_TEMPERATURE = 20; int PRIORITY_SKIN_TEMPERATURE = 21; // The proximity sensor needs the refresh rate to be locked in order to function, so this is // set to a high priority. int PRIORITY_PROXIMITY = 21; int PRIORITY_PROXIMITY = 22; // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order // to function, so this needs to be the highest priority of all votes. int PRIORITY_UDFPS = 22; int PRIORITY_UDFPS = 23; @IntDef(prefix = { "PRIORITY_" }, value = { PRIORITY_DEFAULT_RENDER_FRAME_RATE, Loading @@ -154,6 +160,7 @@ interface Vote { PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE, PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE, PRIORITY_APP_REQUEST_SIZE, PRIORITY_REJECTED_MODES, PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE, PRIORITY_SYNCHRONIZED_REFRESH_RATE, Loading Loading @@ -245,6 +252,10 @@ interface Vote { return new SupportedModesVote(modeIds); } static Vote forRejectedModes(Set<Integer> modeIds) { return new RejectedModesVote(modeIds); } static String priorityToString(int priority) { switch (priority) { case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE: Loading @@ -253,6 +264,8 @@ interface Vote { return "PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE"; case PRIORITY_APP_REQUEST_SIZE: return "PRIORITY_APP_REQUEST_SIZE"; case PRIORITY_REJECTED_MODES: return "PRIORITY_REJECTED_MODES"; case PRIORITY_DEFAULT_RENDER_FRAME_RATE: return "PRIORITY_DEFAULT_REFRESH_RATE"; case PRIORITY_FLICKER_REFRESH_RATE: Loading Loading
services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +9 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,10 @@ public class DisplayManagerFlags { com.android.graphics.surfaceflinger.flags.Flags.FLAG_ENABLE_SMALL_AREA_DETECTION, com.android.graphics.surfaceflinger.flags.Flags::enableSmallAreaDetection); private final FlagState mDisplayConfigErrorHalFlagState = new FlagState( com.android.graphics.surfaceflinger.flags.Flags.FLAG_DISPLAY_CONFIG_ERROR_HAL, com.android.graphics.surfaceflinger.flags.Flags::displayConfigErrorHal); private final FlagState mBrightnessIntRangeUserPerceptionFlagState = new FlagState( Flags.FLAG_BRIGHTNESS_INT_RANGE_USER_PERCEPTION, Flags::brightnessIntRangeUserPerception); Loading Loading @@ -361,6 +365,10 @@ public class DisplayManagerFlags { return mSmallAreaDetectionFlagState.isEnabled(); } public boolean isDisplayConfigErrorHalEnabled() { return mDisplayConfigErrorHalFlagState.isEnabled(); } public boolean isBrightnessIntRangeUserPerceptionEnabled() { return mBrightnessIntRangeUserPerceptionFlagState.isEnabled(); } Loading Loading @@ -591,6 +599,7 @@ public class DisplayManagerFlags { pw.println(" " + mPowerThrottlingClamperFlagState); pw.println(" " + mEvenDimmerFlagState); pw.println(" " + mSmallAreaDetectionFlagState); pw.println(" " + mDisplayConfigErrorHalFlagState); pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState); pw.println(" " + mRestrictDisplayModes); pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState); Loading
services/core/java/com/android/server/display/mode/DisplayModeDirector.java +5 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,7 @@ public class DisplayModeDirector { private final ProximitySensorObserver mSensorObserver; private final HbmObserver mHbmObserver; private final SkinThermalStatusObserver mSkinThermalStatusObserver; private final ModeChangeObserver mModeChangeObserver; @Nullable private final SystemRequestObserver mSystemRequestObserver; Loading Loading @@ -247,6 +248,7 @@ public class DisplayModeDirector { mDisplayObserver = new DisplayObserver(context, handler, mVotesStorage, injector); mSensorObserver = new ProximitySensorObserver(mVotesStorage, injector); mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, mVotesStorage); mModeChangeObserver = new ModeChangeObserver(mVotesStorage, injector, handler.getLooper()); mHbmObserver = new HbmObserver(injector, mVotesStorage, BackgroundThread.getHandler(), mDeviceConfigDisplaySettings); if (displayManagerFlags.isRestrictDisplayModesEnabled()) { Loading Loading @@ -275,6 +277,9 @@ public class DisplayModeDirector { mSensorObserver.observe(); mHbmObserver.observe(); mSkinThermalStatusObserver.observe(); if (mDisplayManagerFlags.isDisplayConfigErrorHalEnabled()) { mModeChangeObserver.observe(); } synchronized (mLock) { // We may have a listener already registered before the call to start, so go ahead and // notify them to pick up our newly initialized state. Loading
services/core/java/com/android/server/display/mode/ModeChangeObserver.java 0 → 100644 +108 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.display.mode; import android.os.Looper; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayAddress; import android.view.DisplayEventReceiver; import com.android.internal.annotations.KeepForWeakReference; import java.util.HashSet; import java.util.Set; final class ModeChangeObserver { private static final String TAG = "ModeChangeObserver"; private final VotesStorage mVotesStorage; private final DisplayModeDirector.Injector mInjector; @SuppressWarnings("unused") @KeepForWeakReference private DisplayEventReceiver mModeChangeListener; private final SparseArray<Set<Integer>> mRejectedModesByDisplay = new SparseArray<>(); private Looper mLooper; ModeChangeObserver(VotesStorage votesStorage, DisplayModeDirector.Injector injector, Looper looper) { mVotesStorage = votesStorage; mInjector = injector; mLooper = looper; } void observe() { mModeChangeListener = new DisplayEventReceiver(mLooper) { @Override public void onModeRejected(long physicalDisplayId, int modeId) { Slog.d(TAG, "Mode Rejected event received"); int displayId = getLogicalDisplayId(physicalDisplayId); if (displayId < 0) { Slog.e(TAG, "Logical Display Id not found"); return; } populateRejectedModesListByDisplay(displayId, modeId); } @Override public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { Slog.d(TAG, "Hotplug event received"); if (!connected) { int displayId = getLogicalDisplayId(physicalDisplayId); if (displayId < 0) { Slog.e(TAG, "Logical Display Id not found"); return; } clearRejectedModesListByDisplay(displayId); } } }; } private int getLogicalDisplayId(long rejectedModePhysicalDisplayId) { Display[] displays = mInjector.getDisplays(); for (Display display : displays) { DisplayAddress address = display.getAddress(); if (address instanceof DisplayAddress.Physical physical) { long physicalDisplayId = physical.getPhysicalDisplayId(); if (physicalDisplayId == rejectedModePhysicalDisplayId) { return display.getDisplayId(); } } } return -1; } private void populateRejectedModesListByDisplay(int displayId, int rejectedModeId) { Set<Integer> alreadyRejectedModes = mRejectedModesByDisplay.get(displayId); if (alreadyRejectedModes == null) { alreadyRejectedModes = new HashSet<>(); mRejectedModesByDisplay.put(displayId, alreadyRejectedModes); } alreadyRejectedModes.add(rejectedModeId); mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, Vote.forRejectedModes(alreadyRejectedModes)); } private void clearRejectedModesListByDisplay(int displayId) { mRejectedModesByDisplay.remove(displayId); mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, null); } }
services/core/java/com/android/server/display/mode/RejectedModesVote.java 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.display.mode; import android.annotation.NonNull; import java.util.Collections; import java.util.Set; public class RejectedModesVote implements Vote { final Set<Integer> mModeIds; RejectedModesVote(Set<Integer> modeIds) { mModeIds = Collections.unmodifiableSet(modeIds); } @Override public void updateSummary(@NonNull VoteSummary summary) { summary.rejectedModeIds.addAll(mModeIds); } @Override public String toString() { return "RejectedModesVote{ mModeIds=" + mModeIds + " }"; } }
services/core/java/com/android/server/display/mode/Vote.java +28 −15 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Set; interface Vote { // DEFAULT_RENDER_FRAME_RATE votes for render frame rate [0, DEFAULT]. As the lowest Loading Loading @@ -82,68 +83,73 @@ interface Vote { int PRIORITY_APP_REQUEST_SIZE = 7; // PRIORITY_REJECTED_MODES rejects the modes for which the mode config failed // so that the modeset can be retried for next available mode after filtering // out the rejected modes for the connected display int PRIORITY_REJECTED_MODES = 8; // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE restricts physical refresh rate to // [0, max(PEAK, MIN)], depending on user settings peakRR/minRR values int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 8; int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 9; // PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE has a higher priority than // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE and will limit render rate to [0, max(PEAK, MIN)] // in case physical refresh rate vote is discarded (due to other high priority votes), // render rate vote can still apply int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 9; int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 10; // Restrict all displays physical refresh rate to 60Hz when external display is connected. // It votes [59Hz, 61Hz]. int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 10; int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 11; // PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE has a higher priority than // PRIORITY_SYNCHRONIZED_REFRESH_RATE and will limit render rate to [59Hz, 61Hz]. // In case physical refresh rate vote discarded (due to physical refresh rate not supported), // render rate vote can still apply. int PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE = 11; int PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE = 12; // Restrict displays max available resolution and refresh rates. It votes [0, LIMIT] int PRIORITY_LIMIT_MODE = 12; int PRIORITY_LIMIT_MODE = 13; // To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh // rate to max value (same as for PRIORITY_UDFPS) on lock screen int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 13; int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 14; // For concurrent displays we want to limit refresh rate on all displays int PRIORITY_LAYOUT_LIMITED_REFRESH_RATE = 14; int PRIORITY_LAYOUT_LIMITED_REFRESH_RATE = 15; // For concurrent displays we want to limit refresh rate on all displays int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 15; int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 16; // For internal application to limit display modes to specific ids int PRIORITY_SYSTEM_REQUESTED_MODES = 16; int PRIORITY_SYSTEM_REQUESTED_MODES = 17; // PRIORITY_LOW_POWER_MODE_MODES limits display modes to specific refreshRate-vsync pairs if // Settings.Global.LOW_POWER_MODE is on. // Lower priority that PRIORITY_LOW_POWER_MODE_RENDER_RATE and if discarded (due to other // higher priority votes), render rate limit can still apply int PRIORITY_LOW_POWER_MODE_MODES = 17; int PRIORITY_LOW_POWER_MODE_MODES = 18; // PRIORITY_LOW_POWER_MODE_RENDER_RATE force the render frame rate to [0, 60HZ] if // Settings.Global.LOW_POWER_MODE is on. int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 18; int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 19; // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the // higher priority voters' result is a range, it will fix the rate to a single choice. // It's used to avoid refresh rate switches in certain conditions which may result in the // user seeing the display flickering when the switches occur. int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 19; int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 20; // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL. int PRIORITY_SKIN_TEMPERATURE = 20; int PRIORITY_SKIN_TEMPERATURE = 21; // The proximity sensor needs the refresh rate to be locked in order to function, so this is // set to a high priority. int PRIORITY_PROXIMITY = 21; int PRIORITY_PROXIMITY = 22; // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order // to function, so this needs to be the highest priority of all votes. int PRIORITY_UDFPS = 22; int PRIORITY_UDFPS = 23; @IntDef(prefix = { "PRIORITY_" }, value = { PRIORITY_DEFAULT_RENDER_FRAME_RATE, Loading @@ -154,6 +160,7 @@ interface Vote { PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE, PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE, PRIORITY_APP_REQUEST_SIZE, PRIORITY_REJECTED_MODES, PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE, PRIORITY_SYNCHRONIZED_REFRESH_RATE, Loading Loading @@ -245,6 +252,10 @@ interface Vote { return new SupportedModesVote(modeIds); } static Vote forRejectedModes(Set<Integer> modeIds) { return new RejectedModesVote(modeIds); } static String priorityToString(int priority) { switch (priority) { case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE: Loading @@ -253,6 +264,8 @@ interface Vote { return "PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE"; case PRIORITY_APP_REQUEST_SIZE: return "PRIORITY_APP_REQUEST_SIZE"; case PRIORITY_REJECTED_MODES: return "PRIORITY_REJECTED_MODES"; case PRIORITY_DEFAULT_RENDER_FRAME_RATE: return "PRIORITY_DEFAULT_REFRESH_RATE"; case PRIORITY_FLICKER_REFRESH_RATE: Loading