diff options
6 files changed, 102 insertions, 17 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index fe422dbea41f..fc9e585400c6 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -805,6 +805,14 @@ <dimen name="global_actions_top_padding">100dp</dimen> + <!-- the maximum offset in either direction that elements are moved horizontally to prevent + burn-in on AOD --> + <dimen name="burn_in_prevention_offset_x">8dp</dimen> + + <!-- the maximum offset in either direction that elements are moved vertically to prevent + burn-in on AOD --> + <dimen name="burn_in_prevention_offset_y">50dp</dimen> + <dimen name="corner_size">16dp</dimen> <dimen name="top_padding">0dp</dimen> <dimen name="bottom_padding">48dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index d2c0f64b5c9b..67ea25870a45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -650,6 +650,10 @@ public class NotificationShelf extends ActivatableNotificationView implements updateRelativeOffset(); } + public void setDarkOffsetX(int offsetX) { + mShelfIcons.setDarkOffsetX(offsetX); + } + private class ShelfState extends ExpandableViewState { private float openedAmount; private boolean hasItemsInStableShelf; 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 7370c03110e6..652288d57fe3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -16,13 +16,14 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate; + import android.content.res.Resources; import android.graphics.Path; import android.view.animation.AccelerateInterpolator; import android.view.animation.PathInterpolator; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.NotificationUtils; /** * Utility class to calculate the clock position and top padding of notifications on Keyguard. @@ -40,6 +41,10 @@ public class KeyguardClockPositionAlgorithm { private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f; private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f; + private static final long MILLIS_PER_MINUTES = 1000 * 60; + private static final float BURN_IN_PREVENTION_PERIOD_Y = 521; + private static final float BURN_IN_PREVENTION_PERIOD_X = 83; + private int mClockNotificationsMarginMin; private int mClockNotificationsMarginMax; private float mClockYFractionMin; @@ -52,6 +57,8 @@ public class KeyguardClockPositionAlgorithm { private int mKeyguardStatusHeight; private float mEmptyDragAmount; private float mDensity; + private int mBurnInPreventionOffsetX; + private int mBurnInPreventionOffsetY; /** * The number (fractional) of notifications the "more" card counts when calculating how many @@ -86,6 +93,10 @@ public class KeyguardClockPositionAlgorithm { (float) res.getDimensionPixelSize(R.dimen.notification_shelf_height) / res.getDimensionPixelSize(R.dimen.notification_min_height); mDensity = res.getDisplayMetrics().density; + mBurnInPreventionOffsetX = res.getDimensionPixelSize( + R.dimen.burn_in_prevention_offset_x); + mBurnInPreventionOffsetY = res.getDimensionPixelSize( + R.dimen.burn_in_prevention_offset_y); } public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight, @@ -122,10 +133,12 @@ public class KeyguardClockPositionAlgorithm { y + getClockNotificationsPadding() + mKeyguardStatusHeight); result.clockAlpha = getClockAlpha(result.clockScale); - result.stackScrollerPadding = (int) NotificationUtils.interpolate( + result.stackScrollerPadding = (int) interpolate( result.stackScrollerPadding, mClockBottom + y, mDarkAmount); + + result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount); } private float getClockScale(int notificationPadding, int clockY, int startPadding) { @@ -154,9 +167,39 @@ public class KeyguardClockPositionAlgorithm { private int getClockY() { // Dark: Align the bottom edge of the clock at one third: // clockBottomEdge = result - mKeyguardStatusHeight / 2 + mClockBottom - float clockYDark = (0.33f * mHeight + (float) mKeyguardStatusHeight / 2 - mClockBottom); + float clockYDark = (0.33f * mHeight + (float) mKeyguardStatusHeight / 2 - mClockBottom) + + burnInPreventionOffsetY(); float clockYRegular = getClockYFraction() * mHeight; - return (int) NotificationUtils.interpolate(clockYRegular, clockYDark, mDarkAmount); + return (int) interpolate(clockYRegular, clockYDark, mDarkAmount); + } + + private float burnInPreventionOffsetY() { + return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES, + mBurnInPreventionOffsetY * 2, + BURN_IN_PREVENTION_PERIOD_Y) + - mBurnInPreventionOffsetY; + } + + private float burnInPreventionOffsetX() { + return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES, + mBurnInPreventionOffsetX * 2, + BURN_IN_PREVENTION_PERIOD_X) + - mBurnInPreventionOffsetX; + } + + /** + * Implements a continuous, piecewise linear, periodic zig-zag function + * + * Can be thought of as a linear approximation of abs(sin(x))) + * + * @param period period of the function, ie. zigzag(x + period) == zigzag(x) + * @param amplitude maximum value of the function + * @return a value between 0 and amplitude + */ + private float zigzag(float x, float amplitude, float period) { + float xprime = (x % period) / (period / 2); + float interpolationAmount = (xprime <= 1) ? xprime : (2 - xprime); + return interpolate(0, amplitude, interpolationAmount); } private float getClockYExpansionAdjustment() { @@ -230,5 +273,8 @@ public class KeyguardClockPositionAlgorithm { * the padding, but not the overall panel size. */ public int stackScrollerPaddingAdjustment; + + /** The x translation of the clock. */ + public int clockX; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index a4fadc4317d9..021e11acbcf5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -123,6 +123,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { private boolean mDisallowNextAnimation; private boolean mAnimationsEnabled = true; private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons; + private int mDarkOffsetX; public NotificationIconContainer(Context context, AttributeSet attrs) { super(context, attrs); @@ -389,6 +390,14 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { iconState.xTranslation = getWidth() - iconState.xTranslation - view.getWidth(); } } + + if (mDark && mDarkOffsetX != 0) { + for (int i = 0; i < childCount; i++) { + View view = getChildAt(i); + IconState iconState = mIconStates.get(view); + iconState.xTranslation += mDarkOffsetX; + } + } } private float getLayoutEnd() { @@ -512,6 +521,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { mReplacingIcons = replacingIcons; } + public void setDarkOffsetX(int offsetX) { + mDarkOffsetX = offsetX; + } + public class IconState extends ViewState { public float iconAppearAmount = 1.0f; public float clampedAppearAmount = 1.0f; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index e2b9da04fed2..4701f85c5ff3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.ActivityManager; @@ -43,15 +44,13 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; -import android.widget.TextView; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.DejankUtils; -import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.SystemUIFactory; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; @@ -69,7 +68,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; -import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.stack.StackStateAnimator; @@ -168,8 +166,9 @@ public class NotificationPanelView extends PanelView implements private int mUnlockMoveDistance; private float mEmptyDragAmount; - private ObjectAnimator mClockAnimator; - private int mClockAnimationTarget = -1; + private Animator mClockAnimator; + private int mClockAnimationTargetX = Integer.MIN_VALUE; + private int mClockAnimationTargetY = Integer.MIN_VALUE; private int mTopPaddingAdjustment; private KeyguardClockPositionAlgorithm mClockPositionAlgorithm = new KeyguardClockPositionAlgorithm(); @@ -459,8 +458,9 @@ public class NotificationPanelView extends PanelView implements mDarkAmount); mClockPositionAlgorithm.run(mClockPositionResult); if (animate || mClockAnimator != null) { - startClockAnimation(mClockPositionResult.clockY); + startClockAnimation(mClockPositionResult.clockX, mClockPositionResult.clockY); } else { + mKeyguardStatusView.setX(mClockPositionResult.clockX); mKeyguardStatusView.setY(mClockPositionResult.clockY); } updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale); @@ -468,6 +468,7 @@ public class NotificationPanelView extends PanelView implements mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment; } mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding); + mNotificationStackScroller.setDarkShelfOffsetX(mClockPositionResult.clockX); requestScrollerTopPaddingUpdate(animate); } @@ -523,11 +524,12 @@ public class NotificationPanelView extends PanelView implements return count; } - private void startClockAnimation(int y) { - if (mClockAnimationTarget == y) { + private void startClockAnimation(int x, int y) { + if (mClockAnimationTargetX == x && mClockAnimationTargetY == y) { return; } - mClockAnimationTarget = y; + mClockAnimationTargetX = x; + mClockAnimationTargetY = y; getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { @@ -536,15 +538,20 @@ public class NotificationPanelView extends PanelView implements mClockAnimator.removeAllListeners(); mClockAnimator.cancel(); } - mClockAnimator = ObjectAnimator - .ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget); + AnimatorSet set = new AnimatorSet(); + set.play(ObjectAnimator.ofFloat( + mKeyguardStatusView, View.Y, mClockAnimationTargetY)) + .with(ObjectAnimator.ofFloat( + mKeyguardStatusView, View.X, mClockAnimationTargetX)); + mClockAnimator = set; mClockAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); mClockAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mClockAnimator = null; - mClockAnimationTarget = -1; + mClockAnimationTargetX = Integer.MIN_VALUE; + mClockAnimationTargetY = Integer.MIN_VALUE; } }); mClockAnimator.start(); @@ -2613,6 +2620,9 @@ public class NotificationPanelView extends PanelView implements public void refreshTime() { mKeyguardStatusView.refreshTime(); + if (mDarkAmount > 0) { + positionClockAndNotifications(); + } } public void setStatusAccessibilityImportance(int mode) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index a3d812cc0796..cbd315b940f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -4252,6 +4252,10 @@ public class NotificationStackScrollLayout extends ViewGroup mHeadsUpGoingAwayAnimationsAllowed = headsUpGoingAwayAnimationsAllowed; } + public void setDarkShelfOffsetX(int shelfOffsetX) { + mShelf.setDarkOffsetX(shelfOffsetX); + } + /** * A listener that is notified when some child locations might have changed. */ |