diff options
author | John Spurlock <jspurlock@google.com> | 2013-10-21 09:32:25 -0400 |
---|---|---|
committer | John Spurlock <jspurlock@google.com> | 2013-10-22 15:39:54 -0400 |
commit | 42197263bc08843ad18a8660887ef540c630c232 (patch) | |
tree | 3835ebade69099147db2d50d507e9c7598a53cfe /packages/SystemUI | |
parent | a81736a74dff602de0412bb5ca4d366007278b74 (diff) | |
download | frameworks_base-42197263bc08843ad18a8660887ef540c630c232.zip frameworks_base-42197263bc08843ad18a8660887ef540c630c232.tar.gz frameworks_base-42197263bc08843ad18a8660887ef540c630c232.tar.bz2 |
Optimize system bar background drawable.
Out with TransitionDrawable.
The new background drawable knows about all possible
background styles, and optimizes the transitions
between them - including picking up from the current
state, force finishing on screen off, and using
SystemClock.elapsedRealtime() for timing.
Bug:11254317
Change-Id: Ice83dc966f6674ef97f7008f2a1b62d67ec59e7d
Diffstat (limited to 'packages/SystemUI')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java | 214 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | 8 |
2 files changed, 141 insertions, 81 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java index 1c8702a..8ad538b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -16,16 +16,20 @@ package com.android.systemui.statusbar.phone; -import android.animation.ArgbEvaluator; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.animation.TimeInterpolator; import android.app.ActivityManager; +import android.content.Context; import android.content.res.Resources; -import android.graphics.drawable.ColorDrawable; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.PixelFormat; +import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.graphics.drawable.TransitionDrawable; +import android.os.SystemClock; import android.util.Log; import android.view.View; +import android.view.animation.LinearInterpolator; import com.android.systemui.R; @@ -45,43 +49,16 @@ public class BarTransitions { private final String mTag; private final View mView; private final boolean mSupportsTransitions = ActivityManager.isHighEndGfx(); - - private final int mOpaque; - private final int mSemiTransparent; + private final BarBackgroundDrawable mBarBackground; private int mMode; - private ValueAnimator mColorDrawableAnimator; - private boolean mColorDrawableShowing; - - private final ColorDrawable mColorDrawable; - private final TransitionDrawable mTransitionDrawable; - private final AnimatorUpdateListener mAnimatorListener = new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animator) { - mColorDrawable.setColor((Integer) animator.getAnimatedValue()); - } - }; public BarTransitions(View view, int gradientResourceId) { mTag = "BarTransitions." + view.getClass().getSimpleName(); mView = view; - final Resources res = mView.getContext().getResources(); - - if (DEBUG_COLORS) { - mOpaque = 0xff0000ff; - mSemiTransparent = 0x7f0000ff; - } else { - mOpaque = res.getColor(R.color.system_bar_background_opaque); - mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent); - } - - mColorDrawable = new ColorDrawable(mOpaque); - mTransitionDrawable = new TransitionDrawable( - new Drawable[] { res.getDrawable(gradientResourceId), mColorDrawable }); - mTransitionDrawable.setCrossFadeEnabled(true); - mTransitionDrawable.resetTransition(); + mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId); if (mSupportsTransitions) { - mView.setBackground(mTransitionDrawable); + mView.setBackground(mBarBackground); } } @@ -100,65 +77,140 @@ public class BarTransitions { } } - private Integer getBackgroundColor(int mode) { - if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent; - if (mode == MODE_OPAQUE) return mOpaque; - if (mode == MODE_LIGHTS_OUT) return mOpaque; - return null; - } - protected void onTransition(int oldMode, int newMode, boolean animate) { applyModeBackground(oldMode, newMode, animate); } protected void applyModeBackground(int oldMode, int newMode, boolean animate) { - if (DEBUG) Log.d(mTag, String.format("applyModeBackground %s animate=%s", - modeToString(newMode), animate)); - cancelColorAnimation(); - Integer oldColor = getBackgroundColor(oldMode); - Integer newColor = getBackgroundColor(newMode); - if (newColor != null) { - if (animate && oldColor != null && !oldColor.equals(newColor)) { - startColorAnimation(oldColor, newColor); - } else if (!newColor.equals(mColorDrawable.getColor())) { - if (DEBUG) Log.d(mTag, String.format("setColor = %08x", newColor)); - mColorDrawable.setColor(newColor); + if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s", + modeToString(oldMode), modeToString(newMode), animate)); + mBarBackground.applyModeBackground(oldMode, newMode, animate); + } + + public static String modeToString(int mode) { + if (mode == MODE_OPAQUE) return "MODE_OPAQUE"; + if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT"; + if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT"; + if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT"; + throw new IllegalArgumentException("Unknown mode " + mode); + } + + public void finishAnimations() { + mBarBackground.finishAnimation(); + } + + private static class BarBackgroundDrawable extends Drawable { + private final int mOpaque; + private final int mSemiTransparent; + private final Drawable mGradient; + private final TimeInterpolator mInterpolator; + + private int mMode = -1; + private boolean mAnimating; + private long mStartTime; + private long mEndTime; + + private int mGradientAlpha; + private int mColor; + + private int mGradientAlphaStart; + private int mColorStart; + + public BarBackgroundDrawable(Context context, int gradientResourceId) { + final Resources res = context.getResources(); + if (DEBUG_COLORS) { + mOpaque = 0xff0000ff; + mSemiTransparent = 0x7f0000ff; + } else { + mOpaque = res.getColor(R.color.system_bar_background_opaque); + mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent); } + mGradient = res.getDrawable(gradientResourceId); + mInterpolator = new LinearInterpolator(); } - if (newColor == null && mColorDrawableShowing) { - if (DEBUG) Log.d(mTag, "Hide color layer"); + + @Override + public void setAlpha(int alpha) { + // noop + } + + @Override + public void setColorFilter(ColorFilter cf) { + // noop + } + + @Override + protected void onBoundsChange(Rect bounds) { + super.onBoundsChange(bounds); + mGradient.setBounds(bounds); + } + + public void applyModeBackground(int oldMode, int newMode, boolean animate) { + if (mMode == newMode) return; + mMode = newMode; + mAnimating = animate; if (animate) { - mTransitionDrawable.reverseTransition(BACKGROUND_DURATION); - } else { - mTransitionDrawable.resetTransition(); + long now = SystemClock.elapsedRealtime(); + mStartTime = now; + mEndTime = now + BACKGROUND_DURATION; + mGradientAlphaStart = mGradientAlpha; + mColorStart = mColor; } - mColorDrawableShowing = false; - } else if (newColor != null && !mColorDrawableShowing) { - if (DEBUG) Log.d(mTag, "Show color layer"); - mTransitionDrawable.startTransition(animate ? BACKGROUND_DURATION : 0); - mColorDrawableShowing = true; + invalidateSelf(); } - } - private void startColorAnimation(int from, int to) { - if (DEBUG) Log.d(mTag, String.format("startColorAnimation %08x -> %08x", from, to)); - mColorDrawableAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to); - mColorDrawableAnimator.addUpdateListener(mAnimatorListener); - mColorDrawableAnimator.start(); - } + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } - private void cancelColorAnimation() { - if (mColorDrawableAnimator != null && mColorDrawableAnimator.isStarted()) { - mColorDrawableAnimator.cancel(); - mColorDrawableAnimator = null; + public void finishAnimation() { + if (mAnimating) { + mAnimating = false; + invalidateSelf(); + } } - } - public static String modeToString(int mode) { - if (mode == MODE_OPAQUE) return "MODE_OPAQUE"; - if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT"; - if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT"; - if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT"; - throw new IllegalArgumentException("Unknown mode " + mode); + @Override + public void draw(Canvas canvas) { + int targetGradientAlpha = 0, targetColor = 0; + if (mMode == MODE_TRANSLUCENT) { + targetGradientAlpha = 0xff; + } else if (mMode == MODE_SEMI_TRANSPARENT) { + targetColor = mSemiTransparent; + } else { + targetColor = mOpaque; + } + if (!mAnimating) { + mColor = targetColor; + mGradientAlpha = targetGradientAlpha; + } else { + final long now = SystemClock.elapsedRealtime(); + if (now >= mEndTime) { + mAnimating = false; + mColor = targetColor; + mGradientAlpha = targetGradientAlpha; + } else { + final float t = (now - mStartTime) / (float)(mEndTime - mStartTime); + final float v = Math.max(0, Math.min(mInterpolator.getInterpolation(t), 1)); + mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v)); + mColor = Color.argb( + (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)), + (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)), + (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)), + (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v))); + } + } + if (mGradientAlpha > 0) { + mGradient.setAlpha(mGradientAlpha); + mGradient.draw(canvas); + } + if (Color.alpha(mColor) > 0) { + canvas.drawColor(mColor); + } + if (mAnimating) { + invalidateSelf(); // keep going + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 925179d..39a9ba7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1945,6 +1945,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { transitions.transitionTo(mode, anim); } + private void finishBarAnimations() { + mStatusBarView.getBarTransitions().finishAnimations(); + if (mNavigationBarView != null) { + mNavigationBarView.getBarTransitions().finishAnimations(); + } + } + private final Runnable mCheckBarModes = new Runnable() { @Override public void run() { @@ -2449,6 +2456,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { makeExpandedInvisible(); notifyNavigationBarScreenOn(false); notifyHeadsUpScreenOn(false); + finishBarAnimations(); } else if (Intent.ACTION_SCREEN_ON.equals(action)) { mScreenOn = true; |