From c9a0088ee03dcbd293453d1394fc44feec9f6127 Mon Sep 17 00:00:00 2001 From: Oleg Petsjonkin Date: Thu, 19 Jan 2023 16:37:17 +0000 Subject: [PATCH] adding new refresh rate priority new priority for auth screen. this allow to request higher refresh rate for screens where auth possible, and avoid swithcing rate when LHBM mode is activated Test: atest DisplayModeDirectorTest Change-Id: I2c19941dd9507d7e9171e30f6f433384ef620a92 --- .../IUdfpsRefreshRateRequestCallback.aidl | 10 +++ .../server/display/DisplayModeDirector.java | 72 +++++++++++++------ .../display/DisplayModeDirectorTest.java | 68 ++++++++++++++++++ 3 files changed, 127 insertions(+), 23 deletions(-) diff --git a/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl b/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl index 8587348ef38b5..7844b40c71a67 100644 --- a/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl +++ b/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl @@ -39,5 +39,15 @@ oneway interface IUdfpsRefreshRateRequestCallback { * {@link android.view.Display#getDisplayId()}. */ void onRequestDisabled(int displayId); + + /** + * To avoid delay in switching refresh rate when activating LHBM, allow screens to request + * higher refersh rate if auth is possible on particular screen + * + * @param displayId The displayId for which the refresh rate should be unset. See + * {@link android.view.Display#getDisplayId()}. + * @param isPossible If authentication is possible on particualr screen + */ + void onAuthenticationPossible(int displayId, boolean isPossible); } diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 29caefbfd1d9d..91ef167dfc3a6 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -733,7 +733,7 @@ public class DisplayModeDirector { /** * Sets the display mode switching type. - * @param newType + * @param newType new mode switching type */ public void setModeSwitchingType(@DisplayManager.SwitchingType int newType) { synchronized (mLock) { @@ -850,6 +850,18 @@ public class DisplayModeDirector { notifyDesiredDisplayModeSpecsChangedLocked(); } + @GuardedBy("mLock") + private float getMaxRefreshRateLocked(int displayId) { + Display.Mode[] modes = mSupportedModesByDisplay.get(displayId); + float maxRefreshRate = 0f; + for (Display.Mode mode : modes) { + if (mode.getRefreshRate() > maxRefreshRate) { + maxRefreshRate = mode.getRefreshRate(); + } + } + return maxRefreshRate; + } + private void notifyDesiredDisplayModeSpecsChangedLocked() { if (mDesiredDisplayModeSpecsListener != null && !mHandler.hasMessages(MSG_REFRESH_RATE_RANGE_CHANGED)) { @@ -1186,29 +1198,33 @@ public class DisplayModeDirector { // rest of low priority voters. It votes [0, max(PEAK, MIN)] public static final int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 7; + // 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 + public static final int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 8; + // For concurrent displays we want to limit refresh rate on all displays - public static final int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 8; + public static final int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 9; // LOW_POWER_MODE force the render frame rate to [0, 60HZ] if // Settings.Global.LOW_POWER_MODE is on. - public static final int PRIORITY_LOW_POWER_MODE = 9; + public static final int PRIORITY_LOW_POWER_MODE = 10; // 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. - public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 10; + public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 11; // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL. - public static final int PRIORITY_SKIN_TEMPERATURE = 11; + public static final int PRIORITY_SKIN_TEMPERATURE = 12; // The proximity sensor needs the refresh rate to be locked in order to function, so this is // set to a high priority. - public static final int PRIORITY_PROXIMITY = 12; + public static final int PRIORITY_PROXIMITY = 13; // 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. - public static final int PRIORITY_UDFPS = 13; + public static final int PRIORITY_UDFPS = 14; // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString. @@ -1325,6 +1341,8 @@ public class DisplayModeDirector { return "PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE"; case PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE: return "PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE"; + case PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE: + return "PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE"; default: return Integer.toString(priority); } @@ -2564,6 +2582,7 @@ public class DisplayModeDirector { private class UdfpsObserver extends IUdfpsRefreshRateRequestCallback.Stub { private final SparseBooleanArray mUdfpsRefreshRateEnabled = new SparseBooleanArray(); + private final SparseBooleanArray mAuthenticationPossible = new SparseBooleanArray(); public void observe() { StatusBarManagerInternal statusBar = @@ -2576,38 +2595,38 @@ public class DisplayModeDirector { @Override public void onRequestEnabled(int displayId) { synchronized (mLock) { - updateRefreshRateStateLocked(displayId, true /*enabled*/); + mUdfpsRefreshRateEnabled.put(displayId, true); + updateVoteLocked(displayId, true, Vote.PRIORITY_UDFPS); } } @Override public void onRequestDisabled(int displayId) { synchronized (mLock) { - updateRefreshRateStateLocked(displayId, false /*enabled*/); + mUdfpsRefreshRateEnabled.put(displayId, false); + updateVoteLocked(displayId, false, Vote.PRIORITY_UDFPS); } } - private void updateRefreshRateStateLocked(int displayId, boolean enabled) { - mUdfpsRefreshRateEnabled.put(displayId, enabled); - updateVoteLocked(displayId); + @Override + public void onAuthenticationPossible(int displayId, boolean isPossible) { + synchronized (mLock) { + mAuthenticationPossible.put(displayId, isPossible); + updateVoteLocked(displayId, isPossible, + Vote.PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE); + } } - private void updateVoteLocked(int displayId) { + @GuardedBy("mLock") + private void updateVoteLocked(int displayId, boolean enabled, int votePriority) { final Vote vote; - if (mUdfpsRefreshRateEnabled.get(displayId)) { - Display.Mode[] modes = mSupportedModesByDisplay.get(displayId); - float maxRefreshRate = 0f; - for (Display.Mode mode : modes) { - if (mode.getRefreshRate() > maxRefreshRate) { - maxRefreshRate = mode.getRefreshRate(); - } - } + if (enabled) { + float maxRefreshRate = DisplayModeDirector.this.getMaxRefreshRateLocked(displayId); vote = Vote.forPhysicalRefreshRates(maxRefreshRate, maxRefreshRate); } else { vote = null; } - - DisplayModeDirector.this.updateVoteLocked(displayId, Vote.PRIORITY_UDFPS, vote); + DisplayModeDirector.this.updateVoteLocked(displayId, votePriority, vote); } void dumpLocked(PrintWriter pw) { @@ -2618,6 +2637,13 @@ public class DisplayModeDirector { final String enabled = mUdfpsRefreshRateEnabled.valueAt(i) ? "enabled" : "disabled"; pw.println(" Display " + displayId + ": " + enabled); } + pw.println(" mAuthenticationPossible: "); + for (int i = 0; i < mAuthenticationPossible.size(); i++) { + final int displayId = mAuthenticationPossible.keyAt(i); + final String isPossible = mAuthenticationPossible.valueAt(i) ? "possible" + : "impossible"; + pw.println(" Display " + displayId + ": " + isPossible); + } } } diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java index 27d912be1c0d3..0eff0da0ed3e5 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java @@ -2402,6 +2402,74 @@ public class DisplayModeDirectorTest { eq(lightSensorTwo), anyInt(), any(Handler.class)); } + @Test + public void testAuthenticationPossibleSetsPhysicalRateRangesToMax() throws RemoteException { + DisplayModeDirector director = + createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0); + // don't call director.start(createMockSensorManager()); + // DisplayObserver will reset mSupportedModesByDisplay + director.onBootCompleted(); + ArgumentCaptor captor = + ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class); + verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture()); + + captor.getValue().onAuthenticationPossible(DISPLAY_ID, true); + + Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE); + assertThat(vote.refreshRateRanges.physical.min).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(vote.refreshRateRanges.physical.max).isWithin(FLOAT_TOLERANCE).of(90); + } + + @Test + public void testAuthenticationPossibleUnsetsVote() throws RemoteException { + DisplayModeDirector director = + createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0); + director.start(createMockSensorManager()); + director.onBootCompleted(); + ArgumentCaptor captor = + ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class); + verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture()); + captor.getValue().onAuthenticationPossible(DISPLAY_ID, true); + captor.getValue().onAuthenticationPossible(DISPLAY_ID, false); + + Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE); + assertNull(vote); + } + + @Test + public void testUdfpsRequestSetsPhysicalRateRangesToMax() throws RemoteException { + DisplayModeDirector director = + createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0); + // don't call director.start(createMockSensorManager()); + // DisplayObserver will reset mSupportedModesByDisplay + director.onBootCompleted(); + ArgumentCaptor captor = + ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class); + verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture()); + + captor.getValue().onRequestEnabled(DISPLAY_ID); + + Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS); + assertThat(vote.refreshRateRanges.physical.min).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(vote.refreshRateRanges.physical.max).isWithin(FLOAT_TOLERANCE).of(90); + } + + @Test + public void testUdfpsRequestUnsetsUnsetsVote() throws RemoteException { + DisplayModeDirector director = + createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0); + director.start(createMockSensorManager()); + director.onBootCompleted(); + ArgumentCaptor captor = + ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class); + verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture()); + captor.getValue().onRequestEnabled(DISPLAY_ID); + captor.getValue().onRequestDisabled(DISPLAY_ID); + + Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS); + assertNull(vote); + } + private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) { return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status); }