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

* commit '9e49b5d679672ea4a64382f9a36663c73603961b':
  Move PIN/Pattern appear animation to RenderThread (1/2)
This commit is contained in:
Jorim Jaggi
2015-07-27 19:18:37 +00:00
committed by Android Git Automerger
5 changed files with 242 additions and 82 deletions

View File

@@ -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,14 +719,15 @@ 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,
cellState, null);
}
});
@Override
public void run() {
startRadiusAnimation(mDotSizeActivated/2, mDotSize/2, 192,
mFastOutSlowInInterpolator,
cellState, null);
}
});
startLineEndAnimation(cellState, mInProgressX, mInProgressY,
getCenterXForColumn(cell.column), getCenterYForRow(cell.row));
}
@@ -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;
drawCircle(canvas, (int) centerX, (int) centerY + translationY,
size, drawLookup[i][j], cellState.alpha);
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,
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);

View File

@@ -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

View File

@@ -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

View File

@@ -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,26 +181,65 @@ 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 {
public long[][] delays;
public int maxDelayRowIndex;

View File

@@ -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()) {
setListening(false);
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);
}