From 5c7cee2b3a12b6bc003abd8fca25a840bdf83bd6 Mon Sep 17 00:00:00 2001 From: Michal Brzezinski Date: Wed, 1 Feb 2023 18:00:32 +0000 Subject: [PATCH] Fix heads-up notification being sometimes clipped when pulsing The NSSL top padding is aligned with the clock top. The clock position moves throughout time to avoid pixel burn-in and sometimes the position is above NSSL bounds, which makes the HUN be clipped. The solution is to account for burn-in vertical shift when calculating NSSL position. This means smartspace with clock will not always be aligned with HUN but it's agreed to be the best solution. Also small renaming of burn-in related fields. Test: KeyguardClockPositionAlgorithmTest.java Test: Manually on-device with simulating biggest burn-in shift up Fixes: 260084123 Change-Id: I211b15affef1c84d0b8524134b3af02894faf536 --- .../phone/KeyguardClockPositionAlgorithm.java | 42 ++++++++++++------- .../KeyguardClockPositionAlgorithmTest.java | 13 ++++++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index 01af48616b656..c163a8940baa7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -89,14 +89,19 @@ public class KeyguardClockPositionAlgorithm { private float mPanelExpansion; /** - * Burn-in prevention x translation. + * Max burn-in prevention x translation. */ - private int mBurnInPreventionOffsetX; + private int mMaxBurnInPreventionOffsetX; /** - * Burn-in prevention y translation for clock layouts. + * Max burn-in prevention y translation for clock layouts. */ - private int mBurnInPreventionOffsetYClock; + private int mMaxBurnInPreventionOffsetYClock; + + /** + * Current burn-in prevention y translation. + */ + private float mCurrentBurnInOffsetY; /** * Doze/AOD transition amount. @@ -155,9 +160,9 @@ public class KeyguardClockPositionAlgorithm { mContainerTopPadding = res.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin); - mBurnInPreventionOffsetX = res.getDimensionPixelSize( + mMaxBurnInPreventionOffsetX = res.getDimensionPixelSize( R.dimen.burn_in_prevention_offset_x); - mBurnInPreventionOffsetYClock = res.getDimensionPixelSize( + mMaxBurnInPreventionOffsetYClock = res.getDimensionPixelSize( R.dimen.burn_in_prevention_offset_y_clock); } @@ -215,7 +220,10 @@ public class KeyguardClockPositionAlgorithm { if (mBypassEnabled) { return (int) (mUnlockedStackScrollerPadding + mOverStretchAmount); } else if (mIsSplitShade) { - return clockYPosition - mSplitShadeTopNotificationsMargin + mUserSwitchHeight; + // mCurrentBurnInOffsetY is subtracted to make notifications not follow clock adjustment + // for burn-in. It can make pulsing notification go too high and it will get clipped + return clockYPosition - mSplitShadeTopNotificationsMargin + mUserSwitchHeight + - (int) mCurrentBurnInOffsetY; } else { return clockYPosition + mKeyguardStatusHeight; } @@ -255,11 +263,11 @@ public class KeyguardClockPositionAlgorithm { // This will keep the clock at the top but out of the cutout area float shift = 0; - if (clockY - mBurnInPreventionOffsetYClock < mCutoutTopInset) { - shift = mCutoutTopInset - (clockY - mBurnInPreventionOffsetYClock); + if (clockY - mMaxBurnInPreventionOffsetYClock < mCutoutTopInset) { + shift = mCutoutTopInset - (clockY - mMaxBurnInPreventionOffsetYClock); } - int burnInPreventionOffsetY = mBurnInPreventionOffsetYClock; // requested offset + int burnInPreventionOffsetY = mMaxBurnInPreventionOffsetYClock; // requested offset final boolean hasUdfps = mUdfpsTop > -1; if (hasUdfps && !mIsClockTopAligned) { // ensure clock doesn't overlap with the udfps icon @@ -267,8 +275,8 @@ public class KeyguardClockPositionAlgorithm { // sometimes the clock textView extends beyond udfps, so let's just use the // space above the KeyguardStatusView/clock as our burn-in offset burnInPreventionOffsetY = (int) (clockY - mCutoutTopInset) / 2; - if (mBurnInPreventionOffsetYClock < burnInPreventionOffsetY) { - burnInPreventionOffsetY = mBurnInPreventionOffsetYClock; + if (mMaxBurnInPreventionOffsetYClock < burnInPreventionOffsetY) { + burnInPreventionOffsetY = mMaxBurnInPreventionOffsetYClock; } shift = -burnInPreventionOffsetY; } else { @@ -276,16 +284,18 @@ public class KeyguardClockPositionAlgorithm { float lowerSpace = mUdfpsTop - mClockBottom; // center the burn-in offset within the upper + lower space burnInPreventionOffsetY = (int) (lowerSpace + upperSpace) / 2; - if (mBurnInPreventionOffsetYClock < burnInPreventionOffsetY) { - burnInPreventionOffsetY = mBurnInPreventionOffsetYClock; + if (mMaxBurnInPreventionOffsetYClock < burnInPreventionOffsetY) { + burnInPreventionOffsetY = mMaxBurnInPreventionOffsetYClock; } shift = (lowerSpace - upperSpace) / 2; } } + float fullyDarkBurnInOffset = burnInPreventionOffsetY(burnInPreventionOffsetY); float clockYDark = clockY - + burnInPreventionOffsetY(burnInPreventionOffsetY) + + fullyDarkBurnInOffset + shift; + mCurrentBurnInOffsetY = MathUtils.lerp(0, fullyDarkBurnInOffset, darkAmount); return (int) (MathUtils.lerp(clockY, clockYDark, darkAmount) + mOverStretchAmount); } @@ -325,7 +335,7 @@ public class KeyguardClockPositionAlgorithm { } private float burnInPreventionOffsetX() { - return getBurnInOffset(mBurnInPreventionOffsetX, true /* xAxis */); + return getBurnInOffset(mMaxBurnInPreventionOffsetX, true /* xAxis */); } public static class Result { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java index ed3f7100ecc52..7e69efaaa640e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java @@ -263,6 +263,19 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase { assertThat(mClockPosition.stackScrollerPadding).isEqualTo(0); } + @Test + public void notifPositionAlignedWithClockAndBurnInOffsetInSplitShadeMode() { + setSplitShadeTopMargin(100); // this makes clock to be at 100 + givenAOD(); + mIsSplitShade = true; + givenMaxBurnInOffset(100); + givenHighestBurnInOffset(); // this makes clock to be at 200 + // WHEN the position algorithm is run + positionClock(); + // THEN the notif padding adjusts for burn-in offset: clock position - burn-in offset + assertThat(mClockPosition.stackScrollerPadding).isEqualTo(100); + } + @Test public void clockPositionedDependingOnMarginInSplitShade() { setSplitShadeTopMargin(400);