diff options
7 files changed, 181 insertions, 26 deletions
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index f3baf05394a6..5e25d2c9fecb 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -78,13 +78,13 @@ <color name="notification_material_background_color">#ffffffff</color> <!-- The color of the material notification background when dimmed --> - <color name="notification_material_background_dimmed_color">#f2ffffff</color> + <color name="notification_material_background_dimmed_color">#ccffffff</color> <!-- The color of the material notification background when low priority --> <color name="notification_material_background_low_priority_color">#fff5f5f5</color> <!-- The background color of the notification shade --> - <color name="notification_shade_background_color">#fff9f9f9</color> + <color name="notification_shade_background_color">#ffeeeeee</color> <!-- The color of the ripples on the untinted notifications --> <color name="notification_ripple_untinted_color">#28000000</color> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index db58a91011ca..25180a98b673 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; +import android.animation.TimeAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; @@ -33,6 +34,7 @@ import android.view.animation.PathInterpolator; import com.android.systemui.R; import com.android.systemui.classifier.FalsingManager; +import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; /** * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer} @@ -127,6 +129,31 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private FalsingManager mFalsingManager; private boolean mTrackTouch; + private float mNormalBackgroundVisibilityAmount; + private ValueAnimator mFadeInFromDarkAnimator; + private ValueAnimator.AnimatorUpdateListener mBackgroundVisibilityUpdater + = new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + setNormalBackgroundVisibilityAmount(mBackgroundNormal.getAlpha()); + } + }; + private AnimatorListenerAdapter mFadeInEndListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + mFadeInFromDarkAnimator = null; + updateOutlineAlpha(); + } + }; + private ValueAnimator.AnimatorUpdateListener mUpdateOutlineListener + = new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + updateOutlineAlpha(); + } + }; + public ActivatableNotificationView(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); @@ -156,6 +183,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim); updateBackground(); updateBackgroundTint(); + updateOutlineAlpha(); } private final Runnable mTapTimeoutRunnable = new Runnable() { @@ -262,7 +290,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } } - private void startActivateAnimation(boolean reverse) { + private void startActivateAnimation(final boolean reverse) { if (!isAttachedToWindow()) { return; } @@ -307,6 +335,16 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundNormal.animate() .alpha(reverse ? 0f : 1f) .setInterpolator(alphaInterpolator) + .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float animatedFraction = animation.getAnimatedFraction(); + if (reverse) { + animatedFraction = 1.0f - animatedFraction; + } + setNormalBackgroundVisibilityAmount(animatedFraction); + } + }) .setDuration(ACTIVATE_ANIMATION_LENGTH); } @@ -367,8 +405,26 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } else { updateBackground(); } - setOutlineAlpha(dark ? 0f : 1f); - } + updateOutlineAlpha(); + } + + private void updateOutlineAlpha() { + if (mDark) { + setOutlineAlpha(0f); + return; + } + float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED; + alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount); + if (mFadeInFromDarkAnimator != null) { + alpha *= mFadeInFromDarkAnimator.getAnimatedFraction(); + } + setOutlineAlpha(alpha); + } + + public void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) { + mNormalBackgroundVisibilityAmount = normalBackgroundVisibilityAmount; + updateOutlineAlpha(); + } public void setShowingLegacyBackground(boolean showing) { mShowingLegacyBackground = showing; @@ -431,7 +487,15 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView background.setAlpha(1f); } }) + .setUpdateListener(mBackgroundVisibilityUpdater) .start(); + mFadeInFromDarkAnimator = TimeAnimator.ofFloat(0.0f, 1.0f); + mFadeInFromDarkAnimator.setDuration(DARK_ANIMATION_LENGTH); + mFadeInFromDarkAnimator.setStartDelay(delay); + mFadeInFromDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); + mFadeInFromDarkAnimator.addListener(mFadeInEndListener); + mFadeInFromDarkAnimator.addUpdateListener(mUpdateOutlineListener); + mFadeInFromDarkAnimator.start(); } /** @@ -477,6 +541,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundAnimator = null; } }); + mBackgroundAnimator.addUpdateListener(mBackgroundVisibilityUpdater); mBackgroundAnimator.start(); } @@ -494,6 +559,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundNormal.setAlpha(1f); removeCallbacks(mTapTimeoutRunnable); } + setNormalBackgroundVisibilityAmount( + mBackgroundNormal.getVisibility() == View.VISIBLE ? 1.0f : 0.0f); } protected boolean shouldHideBackground() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java index dc983e5a05d6..44c6a5d36c64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java @@ -24,8 +24,6 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; -import com.android.systemui.R; - /** * Like {@link ExpandableView}, but setting an outline for the height and clipping. */ @@ -33,7 +31,7 @@ public abstract class ExpandableOutlineView extends ExpandableView { private final Rect mOutlineRect = new Rect(); private boolean mCustomOutline; - private float mOutlineAlpha = 1f; + private float mOutlineAlpha = -1f; public ExpandableOutlineView(Context context, AttributeSet attrs) { super(context, attrs); @@ -66,8 +64,10 @@ public abstract class ExpandableOutlineView extends ExpandableView { } protected void setOutlineAlpha(float alpha) { - mOutlineAlpha = alpha; - invalidateOutline(); + if (alpha != mOutlineAlpha) { + mOutlineAlpha = alpha; + invalidateOutline(); + } } protected void setOutlineRect(RectF rect) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java index ce436d1e1b83..4e3ecb1c63b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java @@ -57,6 +57,7 @@ public class ScrimView extends View mAlphaAnimator = null; } }; + private Runnable mChangeRunnable; public ScrimView(Context context) { this(context, null); @@ -78,9 +79,7 @@ public class ScrimView extends View protected void onDraw(Canvas canvas) { if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) { PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER; - int color = mScrimColor; - color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color), - Color.green(color), Color.blue(color)); + int color = getScrimColorWithAlpha(); if (!mHasExcludedArea) { canvas.drawColor(color, mode); } else { @@ -106,6 +105,13 @@ public class ScrimView extends View } } + public int getScrimColorWithAlpha() { + int color = mScrimColor; + color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color), + Color.green(color), Color.blue(color)); + return color; + } + public void setDrawAsSrc(boolean asSrc) { mDrawAsSrc = asSrc; mPaint.setXfermode(new PorterDuffXfermode(mDrawAsSrc ? PorterDuff.Mode.SRC @@ -118,6 +124,9 @@ public class ScrimView extends View mIsEmpty = Color.alpha(color) == 0; mScrimColor = color; invalidate(); + if (mChangeRunnable != null) { + mChangeRunnable.run(); + } } } @@ -134,8 +143,13 @@ public class ScrimView extends View if (mAlphaAnimator != null) { mAlphaAnimator.cancel(); } - mViewAlpha = alpha; - invalidate(); + if (alpha != mViewAlpha) { + mViewAlpha = alpha; + invalidate(); + if (mChangeRunnable != null) { + mChangeRunnable.run(); + } + } } public void animateViewAlpha(float alpha, long durationOut, Interpolator interpolator) { @@ -164,4 +178,8 @@ public class ScrimView extends View mHasExcludedArea = area.left < area.right && area.top < area.bottom; invalidate(); } + + public void setChangeRunnable(Runnable changeRunnable) { + mChangeRunnable = changeRunnable; + } } 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 dbf812f4709e..354d704650f6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -3742,7 +3742,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade); updateDozingState(); updatePublicMode(); - updateStackScrollerState(goingToFullShade); + updateStackScrollerState(goingToFullShade, fromShadeLocked); updateNotifications(); checkBarModes(); updateMediaMetaData(false); @@ -3763,11 +3763,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate); } - public void updateStackScrollerState(boolean goingToFullShade) { + public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) { if (mStackScroller == null) return; boolean onKeyguard = mState == StatusBarState.KEYGUARD; mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade); - mStackScroller.setDimmed(onKeyguard, false /* animate */); + mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */); mStackScroller.setExpandingEnabled(!onKeyguard); ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild(); mStackScroller.setActivatedChild(null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 8cbb1ae45a7b..f310c2c2488c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -502,4 +502,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public void setExcludedBackgroundArea(Rect area) { mScrimBehind.setExcludedArea(area); } + + public int getScrimBehindColor() { + return mScrimBehind.getScrimColorWithAlpha(); + } + + public void setScrimBehindChangeRunnable(Runnable changeRunnable) { + mScrimBehind.setChangeRunnable(changeRunnable); + } } 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 4c5ad74ad552..6bc49ff5285b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -20,16 +20,18 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; +import android.animation.TimeAnimator; +import android.animation.ValueAnimator; import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; @@ -72,6 +74,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter, ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener { + public static final float BACKGROUND_ALPHA_DIMMED = 0.7f; private static final String TAG = "NotificationStackScrollLayout"; private static final boolean DEBUG = false; private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f; @@ -87,6 +90,7 @@ public class NotificationStackScrollLayout extends ViewGroup private SwipeHelper mSwipeHelper; private boolean mSwipingInProgress; private int mCurrentStackHeight = Integer.MAX_VALUE; + private final Paint mBackgroundPaint = new Paint(); /** * mCurrentStackHeight is the actual stack height, mLastSetStackHeight is the stack height set @@ -238,7 +242,6 @@ public class NotificationStackScrollLayout extends ViewGroup private NotificationOverflowContainer mOverflowContainer; private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>(); private FalsingManager mFalsingManager; - private ColorDrawable mBackground; private boolean mAnimationRunning; private ViewTreeObserver.OnPreDrawListener mBackgroundUpdater = new ViewTreeObserver.OnPreDrawListener() { @@ -254,13 +257,30 @@ public class NotificationStackScrollLayout extends ViewGroup private Rect mBackgroundBounds = new Rect(); private Rect mStartAnimationRect = new Rect(); private Rect mEndAnimationRect = new Rect(); - private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);; + private Rect mCurrentBounds = new Rect(-1, -1, -1, -1); private boolean mAnimateNextBackgroundBottom; private boolean mAnimateNextBackgroundTop; private ObjectAnimator mBottomAnimator = null; private ObjectAnimator mTopAnimator = null; private ActivatableNotificationView mFirstVisibleBackgroundChild = null; private ActivatableNotificationView mLastVisibleBackgroundChild = null; + private int mBgColor; + private float mDimAmount; + private ValueAnimator mDimAnimator; + private Animator.AnimatorListener mDimEndListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mDimAnimator = null; + } + }; + private ValueAnimator.AnimatorUpdateListener mDimUpdateListener + = new ValueAnimator.AnimatorUpdateListener() { + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + setDimAmount((Float) animation.getAnimatedValue()); + } + }; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -277,9 +297,7 @@ public class NotificationStackScrollLayout extends ViewGroup public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - mBackground = new ColorDrawable(context.getColor( - R.color.notification_shade_background_color)); - mBackground.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); + mBgColor = context.getColor(R.color.notification_shade_background_color); int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height); int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height); mExpandHelper = new ExpandHelper(getContext(), this, @@ -299,11 +317,12 @@ public class NotificationStackScrollLayout extends ViewGroup mDebugPaint.setStyle(Paint.Style.STROKE); } mFalsingManager = FalsingManager.getInstance(context); + mBackgroundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); } @Override protected void onDraw(Canvas canvas) { - mBackground.draw(canvas); + canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint); if (DEBUG) { int y = mTopPadding; canvas.drawLine(0, y, getWidth(), y, mDebugPaint); @@ -319,6 +338,20 @@ public class NotificationStackScrollLayout extends ViewGroup } } + private void updateBackgroundDimming() { + float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount); + // We need to manually blend in the background color + int scrimColor = mScrimController.getScrimBehindColor(); + // SRC_OVER blending Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc + float alphaInv = 1 - alpha; + int color = Color.argb((int) (alpha * 255 + alphaInv * Color.alpha(scrimColor)), + (int) (Color.red(mBgColor) + alphaInv * Color.red(scrimColor)), + (int) (Color.green(mBgColor) + alphaInv * Color.green(scrimColor)), + (int) (Color.blue(mBgColor) + alphaInv * Color.blue(scrimColor))); + mBackgroundPaint.setColor(color); + invalidate(); + } + private void initView(Context context) { mScroller = new OverScroller(getContext()); setFocusable(true); @@ -1569,7 +1602,6 @@ public class NotificationStackScrollLayout extends ViewGroup private void applyCurrentBackgroundBounds() { mScrimController.setExcludedBackgroundArea(mCurrentBounds); - mBackground.setBounds(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom); invalidate(); } @@ -2663,10 +2695,34 @@ public class NotificationStackScrollLayout extends ViewGroup if (animate && mAnimationsEnabled) { mDimmedNeedsAnimation = true; mNeedsAnimation = true; + animateDimmed(dimmed); + } else { + setDimAmount(dimmed ? 1.0f : 0.0f); } requestChildrenUpdate(); } + private void setDimAmount(float dimAmount) { + mDimAmount = dimAmount; + updateBackgroundDimming(); + } + + private void animateDimmed(boolean dimmed) { + if (mDimAnimator != null) { + mDimAnimator.cancel(); + } + float target = dimmed ? 1.0f : 0.0f; + if (target == mDimAmount) { + return; + } + mDimAnimator = TimeAnimator.ofFloat(mDimAmount, target); + mDimAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_DIMMED_ACTIVATED); + mDimAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + mDimAnimator.addListener(mDimEndListener); + mDimAnimator.addUpdateListener(mDimUpdateListener); + mDimAnimator.start(); + } + public void setHideSensitive(boolean hideSensitive, boolean animate) { if (hideSensitive != mAmbientState.isHideSensitive()) { int childCount = getChildCount(); @@ -3108,6 +3164,12 @@ public class NotificationStackScrollLayout extends ViewGroup public void setScrimController(ScrimController scrimController) { mScrimController = scrimController; + mScrimController.setScrimBehindChangeRunnable(new Runnable() { + @Override + public void run() { + updateBackgroundDimming(); + } + }); } public void forceNoOverlappingRendering(boolean force) { |