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

Commit 9e49b5d6 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Move PIN/Pattern appear animation to RenderThread (1/2)" into mnc-dev

parents 01fe3f86 613f55fb
Loading
Loading
Loading
Loading
+145 −23
Original line number Diff line number Diff line
@@ -23,10 +23,10 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Debug;
@@ -38,8 +38,10 @@ import android.provider.Settings;
import android.util.AttributeSet;
import android.util.IntArray;
import android.util.Log;
import android.view.DisplayListCanvas;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -200,10 +202,16 @@ public class LockPatternView extends View {
    }

    public static class CellState {
        public float scale = 1.0f;
        public float translateY = 0.0f;
        public float alpha = 1.0f;
        public float size;
        int row;
        int col;
        boolean hwAnimating;
        CanvasProperty<Float> hwRadius;
        CanvasProperty<Float> hwCenterX;
        CanvasProperty<Float> hwCenterY;
        CanvasProperty<Paint> hwPaint;
        float radius;
        float translationY;
        float alpha = 1f;
        public float lineEndX = Float.MIN_VALUE;
        public float lineEndY = Float.MIN_VALUE;
        public ValueAnimator lineAnimator;
@@ -313,7 +321,9 @@ public class LockPatternView extends View {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                mCellStates[i][j] = new CellState();
                mCellStates[i][j].size = mDotSize;
                mCellStates[i][j].radius = mDotSize/2;
                mCellStates[i][j].row = i;
                mCellStates[i][j].col = j;
            }
        }

@@ -412,6 +422,112 @@ public class LockPatternView extends View {
        invalidate();
    }

    public void startCellStateAnimation(CellState cellState, float startAlpha, float endAlpha,
            float startTranslationY, float endTranslationY, float startScale, float endScale,
            long delay, long duration,
            Interpolator interpolator, Runnable finishRunnable) {
        if (isHardwareAccelerated()) {
            startCellStateAnimationHw(cellState, startAlpha, endAlpha, startTranslationY,
                    endTranslationY, startScale, endScale, delay, duration, interpolator,
                    finishRunnable);
        } else {
            startCellStateAnimationSw(cellState, startAlpha, endAlpha, startTranslationY,
                    endTranslationY, startScale, endScale, delay, duration, interpolator,
                    finishRunnable);
        }
    }

    private void startCellStateAnimationSw(final CellState cellState,
            final float startAlpha, final float endAlpha,
            final float startTranslationY, final float endTranslationY,
            final float startScale, final float endScale,
            long delay, long duration, Interpolator interpolator, final Runnable finishRunnable) {
        cellState.alpha = startAlpha;
        cellState.translationY = startTranslationY;
        cellState.radius = mDotSize/2 * startScale;
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
        animator.setDuration(duration);
        animator.setStartDelay(delay);
        animator.setInterpolator(interpolator);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float t = (float) animation.getAnimatedValue();
                cellState.alpha = (1 - t) * startAlpha + t * endAlpha;
                cellState.translationY = (1 - t) * startTranslationY + t * endTranslationY;
                cellState.radius = mDotSize/2 * ((1 - t) * startScale + t * endScale);
                invalidate();
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (finishRunnable != null) {
                    finishRunnable.run();
                }
            }
        });
        animator.start();
    }

    private void startCellStateAnimationHw(final CellState cellState,
            float startAlpha, float endAlpha,
            float startTranslationY, float endTranslationY,
            float startScale, float endScale,
            long delay, long duration, Interpolator interpolator, final Runnable finishRunnable) {
        cellState.alpha = endAlpha;
        cellState.translationY = endTranslationY;
        cellState.radius = mDotSize/2 * endScale;
        cellState.hwAnimating = true;
        cellState.hwCenterY = CanvasProperty.createFloat(
                getCenterYForRow(cellState.row) + startTranslationY);
        cellState.hwCenterX = CanvasProperty.createFloat(getCenterXForColumn(cellState.col));
        cellState.hwRadius = CanvasProperty.createFloat(mDotSize/2 * startScale);
        mPaint.setColor(getCurrentColor(false));
        mPaint.setAlpha((int) (startAlpha * 255));
        cellState.hwPaint = CanvasProperty.createPaint(new Paint(mPaint));

        startRtFloatAnimation(cellState.hwCenterY,
                getCenterYForRow(cellState.row) + endTranslationY, delay, duration, interpolator);
        startRtFloatAnimation(cellState.hwRadius, mDotSize/2 * endScale, delay, duration,
                interpolator);
        startRtAlphaAnimation(cellState, endAlpha, delay, duration, interpolator,
                new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        cellState.hwAnimating = false;
                        if (finishRunnable != null) {
                            finishRunnable.run();
                        }
                    }
                });

        invalidate();
    }

    private void startRtAlphaAnimation(CellState cellState, float endAlpha,
            long delay, long duration, Interpolator interpolator,
            Animator.AnimatorListener listener) {
        RenderNodeAnimator animator = new RenderNodeAnimator(cellState.hwPaint,
                RenderNodeAnimator.PAINT_ALPHA, (int) (endAlpha * 255));
        animator.setDuration(duration);
        animator.setStartDelay(delay);
        animator.setInterpolator(interpolator);
        animator.setTarget(this);
        animator.addListener(listener);
        animator.start();
    }

    private void startRtFloatAnimation(CanvasProperty<Float> property, float endValue,
            long delay, long duration, Interpolator interpolator) {
        RenderNodeAnimator animator = new RenderNodeAnimator(property, endValue);
        animator.setDuration(duration);
        animator.setStartDelay(delay);
        animator.setInterpolator(interpolator);
        animator.setTarget(this);
        animator.start();
    }

    private void notifyCellAdded() {
        // sendAccessEvent(R.string.lockscreen_access_pattern_cell_added);
        if (mOnPatternListener != null) {
@@ -603,11 +719,12 @@ public class LockPatternView extends View {

    private void startCellActivatedAnimation(Cell cell) {
        final CellState cellState = mCellStates[cell.row][cell.column];
        startSizeAnimation(mDotSize, mDotSizeActivated, 96, mLinearOutSlowInInterpolator,
        startRadiusAnimation(mDotSize/2, mDotSizeActivated/2, 96, mLinearOutSlowInInterpolator,
                cellState, new Runnable() {
                    @Override
                    public void run() {
                startSizeAnimation(mDotSizeActivated, mDotSize, 192, mFastOutSlowInInterpolator,
                        startRadiusAnimation(mDotSizeActivated/2, mDotSize/2, 192,
                                mFastOutSlowInInterpolator,
                                cellState, null);
                    }
                });
@@ -639,13 +756,13 @@ public class LockPatternView extends View {
        state.lineAnimator = valueAnimator;
    }

    private void startSizeAnimation(float start, float end, long duration, Interpolator interpolator,
            final CellState state, final Runnable endRunnable) {
    private void startRadiusAnimation(float start, float end, long duration,
            Interpolator interpolator, final CellState state, final Runnable endRunnable) {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, end);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                state.size = (float) animation.getAnimatedValue();
                state.radius = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
@@ -969,10 +1086,16 @@ public class LockPatternView extends View {
            for (int j = 0; j < 3; j++) {
                CellState cellState = mCellStates[i][j];
                float centerX = getCenterXForColumn(j);
                float size = cellState.size * cellState.scale;
                float translationY = cellState.translateY;
                float translationY = cellState.translationY;
                if (isHardwareAccelerated() && cellState.hwAnimating) {
                    DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
                    displayListCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
                            cellState.hwRadius, cellState.hwPaint);
                } else {
                    drawCircle(canvas, (int) centerX, (int) centerY + translationY,
                        size, drawLookup[i][j], cellState.alpha);
                            cellState.radius, drawLookup[i][j], cellState.alpha);

                }
            }
        }

@@ -1055,11 +1178,11 @@ public class LockPatternView extends View {
    /**
     * @param partOfPattern Whether this circle is part of the pattern.
     */
    private void drawCircle(Canvas canvas, float centerX, float centerY, float size,
    private void drawCircle(Canvas canvas, float centerX, float centerY, float radius,
            boolean partOfPattern, float alpha) {
        mPaint.setColor(getCurrentColor(partOfPattern));
        mPaint.setAlpha((int) (alpha * 255));
        canvas.drawCircle(centerX, centerY, size/2, mPaint);
        canvas.drawCircle(centerX, centerY, radius, mPaint);
    }

    @Override
@@ -1290,7 +1413,6 @@ public class LockPatternView extends View {
            float centerY = getCenterYForRow(row);
            float cellheight = mSquareHeight * mHitFactor * 0.5f;
            float cellwidth = mSquareWidth * mHitFactor * 0.5f;
            float translationY = cell.translateY;
            bounds.left = (int) (centerX - cellwidth);
            bounds.right = (int) (centerX + cellwidth);
            bounds.top = (int) (centerY - cellheight);
+8 −8
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@

package com.android.keyguard;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.RenderNode;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
@@ -114,10 +118,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
        enableClipping(false);
        setAlpha(1f);
        setTranslationY(mAppearAnimationUtils.getStartTranslation());
        animate()
                .setDuration(500)
                .setInterpolator(mAppearAnimationUtils.getInterpolator())
                .translationY(0);
        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
                0, mAppearAnimationUtils.getInterpolator());
        mAppearAnimationUtils.startAnimation2d(mViews,
                new Runnable() {
                    @Override
@@ -131,10 +133,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
    public boolean startDisappearAnimation(final Runnable finishRunnable) {
        enableClipping(false);
        setTranslationY(0);
        animate()
                .setDuration(280)
                .setInterpolator(mDisappearAnimationUtils.getInterpolator())
                .translationY(mDisappearYTranslation);
        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 280 /* duration */,
                mDisappearYTranslation, mDisappearAnimationUtils.getInterpolator());
        mDisappearAnimationUtils.startAnimation2d(mViews,
                new Runnable() {
                    @Override
+12 −40
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.keyguard;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
@@ -27,6 +28,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
@@ -334,10 +336,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
        enableClipping(false);
        setAlpha(1f);
        setTranslationY(mAppearAnimationUtils.getStartTranslation());
        animate()
                .setDuration(500)
                .setInterpolator(mAppearAnimationUtils.getInterpolator())
                .translationY(0);
        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
                0, mAppearAnimationUtils.getInterpolator());
        mAppearAnimationUtils.startAnimation2d(
                mLockPatternView.getCellStates(),
                new Runnable() {
@@ -362,10 +362,9 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
        mLockPatternView.clearPattern();
        enableClipping(false);
        setTranslationY(0);
        animate()
                .setDuration(300)
                .setInterpolator(mDisappearAnimationUtils.getInterpolator())
                .translationY(-mDisappearAnimationUtils.getStartTranslation());
        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 300 /* duration */,
                -mDisappearAnimationUtils.getStartTranslation(),
                mDisappearAnimationUtils.getInterpolator());
        mDisappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(),
                new Runnable() {
                    @Override
@@ -398,43 +397,16 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
            long duration, float translationY, final boolean appearing,
            Interpolator interpolator,
            final Runnable finishListener) {
        if (appearing) {
            animatedCell.scale = 0.0f;
            animatedCell.alpha = 1.0f;
        }
        animatedCell.translateY = appearing ? translationY : 0;
        ValueAnimator animator = ValueAnimator.ofFloat(animatedCell.translateY,
                appearing ? 0 : translationY);
        animator.setInterpolator(interpolator);
        animator.setDuration(duration);
        animator.setStartDelay(delay);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedFraction = animation.getAnimatedFraction();
                if (appearing) {
                    animatedCell.scale = animatedFraction;
                } else {
                    animatedCell.alpha = 1 - animatedFraction;
                }
                animatedCell.translateY = (float) animation.getAnimatedValue();
                mLockPatternView.invalidate();
            }
        });
        mLockPatternView.startCellStateAnimation(animatedCell,
                1f, appearing ? 1f : 0f, /* alpha */
                appearing ? translationY : 0f, appearing ? 0f : translationY, /* translation */
                appearing ? 0f : 1f, 1f /* scale */,
                delay, duration, interpolator, finishListener);
        if (finishListener != null) {
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    finishListener.run();
                }
            });

            // Also animate the Emergency call
            mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, translationY,
                    appearing, interpolator, null);
        }
        animator.start();
        mLockPatternView.invalidate();
    }

    @Override
+56 −10
Original line number Diff line number Diff line
@@ -16,11 +16,18 @@

package com.android.settingslib.animation;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;

import com.android.internal.widget.LockPatternView;
import com.android.settingslib.R;

/**
@@ -174,24 +181,63 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
    }

    @Override
    public void createAnimation(View view, long delay, long duration, float translationY,
            boolean appearing, Interpolator interpolator, Runnable endRunnable) {
    public void createAnimation(final View view, long delay, long duration, float translationY,
            boolean appearing, Interpolator interpolator, final Runnable endRunnable) {
        if (view != null) {
            view.setAlpha(appearing ? 0f : 1.0f);
            view.setTranslationY(appearing ? translationY : 0);
            view.animate()
                    .alpha(appearing ? 1f : 0f)
                    .translationY(appearing ? 0 : translationY)
                    .setInterpolator(interpolator)
                    .setDuration(duration)
                    .setStartDelay(delay);
            Animator alphaAnim;
            float targetAlpha =  appearing ? 1f : 0f;
            if (view.isHardwareAccelerated()) {
                RenderNodeAnimator alphaAnimRt = new RenderNodeAnimator(RenderNodeAnimator.ALPHA,
                        targetAlpha);
                alphaAnimRt.setTarget(view);
                alphaAnim = alphaAnimRt;
            } else {
                alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), targetAlpha);
            }
            alphaAnim.setInterpolator(interpolator);
            alphaAnim.setDuration(duration);
            alphaAnim.setStartDelay(delay);
            if (view.hasOverlappingRendering()) {
                view.animate().withLayer();
                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                alphaAnim.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        view.setLayerType(View.LAYER_TYPE_NONE, null);
                    }
                });
            }
            if (endRunnable != null) {
                view.animate().withEndAction(endRunnable);
                alphaAnim.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        endRunnable.run();
                    }
                });
            }
            alphaAnim.start();
            startTranslationYAnimation(view, delay, duration, appearing ? 0 : translationY,
                    interpolator);
        }
    }

    public static void startTranslationYAnimation(View view, long delay, long duration,
            float endTranslationY, Interpolator interpolator) {
        Animator translationAnim;
        if (view.isHardwareAccelerated()) {
            RenderNodeAnimator translationAnimRt = new RenderNodeAnimator(
                    RenderNodeAnimator.TRANSLATION_Y, endTranslationY);
            translationAnimRt.setTarget(view);
            translationAnim = translationAnimRt;
        } else {
            translationAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,
                    view.getTranslationY(), endTranslationY);
        }
        translationAnim.setInterpolator(interpolator);
        translationAnim.setDuration(duration);
        translationAnim.setStartDelay(delay);
        translationAnim.start();
    }

    public class AppearAnimationProperties {
+21 −1
Original line number Diff line number Diff line
@@ -26,11 +26,13 @@ import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
@@ -42,6 +44,7 @@ import android.widget.TextView;

import com.android.internal.logging.MetricsLogger;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.DejankUtils;
import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
@@ -79,6 +82,8 @@ public class NotificationPanelView extends PanelView implements
    private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
    private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";

    private static final Rect mDummyDirtyRect = new Rect(0, 0, 1, 1);

    public static final long DOZE_ANIMATION_DURATION = 700;

    private KeyguardAffordanceHelper mAfforanceHelper;
@@ -1777,7 +1782,22 @@ public class NotificationPanelView extends PanelView implements
        mIsExpanding = false;
        mScrollYOverride = -1;
        if (isFullyCollapsed()) {
            DejankUtils.postAfterTraversal(new Runnable() {
                @Override
                public void run() {
                    setListening(false);
                }
            });

            // Workaround b/22639032: Make sure we invalidate something because else RenderThread
            // thinks we are actually drawing a frame put in reality we don't, so RT doesn't go
            // ahead with rendering and we jank.
            postOnAnimation(new Runnable() {
                @Override
                public void run() {
                    getParent().invalidateChild(NotificationPanelView.this, mDummyDirtyRect);
                }
            });
        } else {
            setListening(true);
        }