Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc747bd8 authored by Adrian Roos's avatar Adrian Roos
Browse files

AOD: Move clock to prevent burn in

Change-Id: I4d14aac0a379266b3bdef0a588575017ad345c4d
Merged-In: I4d14aac0a379266b3bdef0a588575017ad345c4d
Fixes: 35850027
Test: Enable AOD, observe that clock slightly moves every minute
parent 4317e457
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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>
+4 −0
Original line number Diff line number Diff line
@@ -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;
+50 −4
Original line number Diff line number Diff line
@@ -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;
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -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;
+23 −13
Original line number Diff line number Diff line
@@ -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) {
Loading