AOD - Scale large clock for burn-in protection

Scale the AOD large clock between [0.8, 1.0] in both x,y directions,
in order to keep the clock centered. The large clock will still be
shifted on the y-axis as well.

Bug: 13129102
Test: manual, burn in tests
Change-Id: I86235d39b199a1a10cfb40e474f1e1e58b9c11d8
This commit is contained in:
Matt Pietal
2020-12-01 10:52:28 -05:00
parent 3a9b54f704
commit 60028e89fc
6 changed files with 40 additions and 6 deletions

View File

@@ -62,6 +62,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private AnimatableClockController mNewLockScreenClockViewController;
private FrameLayout mNewLockScreenClockFrame;
private AnimatableClockController mNewLockScreenLargeClockViewController;
private FrameLayout mNewLockScreenLargeClockFrame;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
@@ -126,6 +127,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mView.updateColors(getGradientColors());
updateAodIcons();
mNewLockScreenClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view);
mNewLockScreenLargeClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view_large);
}
@Override
@@ -199,13 +201,18 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
/**
* Update position of the view, with optional animation. Move the slice view and the clock
* slightly towards the center in order to prevent burn-in. Y positioning occurs at the
* view parent level.
* view parent level. The large clock view will scale instead of using x position offsets, to
* keep the clock centered.
*/
void updatePosition(int x, AnimationProperties props, boolean animate) {
void updatePosition(int x, float scale, AnimationProperties props, boolean animate) {
x = Math.abs(x);
if (mNewLockScreenClockFrame != null) {
PropertyAnimator.setProperty(mNewLockScreenClockFrame, AnimatableProperty.TRANSLATION_X,
-x, props, animate);
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_X,
scale, props, animate);
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_Y,
scale, props, animate);
}
mKeyguardSliceViewController.updatePosition(x, props, animate);
mNotificationIconAreaController.updatePosition(x, props, animate);

View File

@@ -193,7 +193,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
/**
* Update position of the view with an optional animation
*/
public void updatePosition(int x, int y, boolean animate) {
public void updatePosition(int x, int y, float scale, boolean animate) {
PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, CLOCK_ANIMATION_PROPERTIES,
animate);
@@ -202,10 +202,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
PropertyAnimator.setProperty(mView, AnimatableProperty.X, 0,
CLOCK_ANIMATION_PROPERTIES, animate);
mKeyguardClockSwitchController.updatePosition(x, CLOCK_ANIMATION_PROPERTIES, animate);
mKeyguardClockSwitchController.updatePosition(x, scale, CLOCK_ANIMATION_PROPERTIES,
animate);
} else {
// reset any prior movement
mKeyguardClockSwitchController.updatePosition(0, CLOCK_ANIMATION_PROPERTIES, animate);
mKeyguardClockSwitchController.updatePosition(0, 0f, CLOCK_ANIMATION_PROPERTIES,
animate);
PropertyAnimator.setProperty(mView, AnimatableProperty.X, x,
CLOCK_ANIMATION_PROPERTIES, animate);

View File

@@ -21,6 +21,7 @@ import android.util.MathUtils
private const val MILLIS_PER_MINUTES = 1000 * 60f
private const val BURN_IN_PREVENTION_PERIOD_Y = 521f
private const val BURN_IN_PREVENTION_PERIOD_X = 83f
private const val BURN_IN_PREVENTION_PERIOD_SCALE = 180f
/**
* Returns the translation offset that should be used to avoid burn in at
@@ -35,6 +36,14 @@ fun getBurnInOffset(amplitude: Int, xAxis: Boolean): Int {
if (xAxis) BURN_IN_PREVENTION_PERIOD_X else BURN_IN_PREVENTION_PERIOD_Y).toInt()
}
/**
* Returns a value to scale a view in order to avoid burn in.
*/
fun getBurnInScale(): Float {
return 0.8f + zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
0.2f, BURN_IN_PREVENTION_PERIOD_SCALE)
}
/**
* Implements a continuous, piecewise linear, periodic zig-zag function
*

View File

@@ -40,6 +40,14 @@ public abstract class AnimatableProperty {
View.TRANSLATION_X, R.id.x_animator_tag, R.id.x_animator_tag_start_value,
R.id.x_animator_tag_end_value);
public static final AnimatableProperty SCALE_X = AnimatableProperty.from(
View.SCALE_X, R.id.scale_x_animator_tag, R.id.scale_x_animator_start_value_tag,
R.id.scale_x_animator_end_value_tag);
public static final AnimatableProperty SCALE_Y = AnimatableProperty.from(
View.SCALE_Y, R.id.scale_y_animator_tag, R.id.scale_y_animator_start_value_tag,
R.id.scale_y_animator_end_value_tag);
/**
* Similar to X, however this doesn't allow for any other modifications other than from this
* property. When using X, it's possible that the view is laid out during the animation,

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInScale;
import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate;
import android.content.res.Resources;
@@ -184,6 +185,7 @@ public class KeyguardClockPositionAlgorithm {
result.stackScrollerPaddingExpanded = mBypassEnabled ? mUnlockedStackScrollerPadding
: getClockY(1.0f) + mKeyguardStatusHeight;
result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
result.clockScale = interpolate(getBurnInScale(), 1.0f, 1.0f - mDarkAmount);
}
/**
@@ -303,6 +305,11 @@ public class KeyguardClockPositionAlgorithm {
*/
public float clockAlpha;
/**
* Amount to scale the large clock (0.0 - 1.0)
*/
public float clockScale;
/**
* The top padding of the stack scroller, in pixels.
*/

View File

@@ -888,7 +888,8 @@ public class NotificationPanelViewController extends PanelViewController {
mUpdateMonitor.isUdfpsEnrolled());
mClockPositionAlgorithm.run(mClockPositionResult);
mKeyguardStatusViewController.updatePosition(
mClockPositionResult.clockX, mClockPositionResult.clockY, animateClock);
mClockPositionResult.clockX, mClockPositionResult.clockY,
mClockPositionResult.clockScale, animateClock);
updateNotificationTranslucency();
updateClock();
stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;