Loading packages/SystemUI/src/com/android/systemui/Interpolators.java +14 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,13 @@ import com.android.systemui.statusbar.stack.HeadsUpAppearInterpolator; */ public class Interpolators { public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f); /** * Like {@link #FAST_OUT_SLOW_IN}, but used in case the animation is played in reverse (i.e. t * goes from 1 to 0 instead of 0 to 1). */ public static final Interpolator FAST_OUT_SLOW_IN_REVERSE = new PathInterpolator(0.8f, 0f, 0.6f, 1f); public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f); public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); Loading @@ -51,4 +58,11 @@ public class Interpolators { */ public static final Interpolator TOUCH_RESPONSE = new PathInterpolator(0.3f, 0f, 0.1f, 1f); /** * Like {@link #TOUCH_RESPONSE}, but used in case the animation is played in reverse (i.e. t * goes from 1 to 0 instead of 0 to 1). */ public static final Interpolator TOUCH_RESPONSE_REVERSE = new PathInterpolator(0.9f, 0f, 0.7f, 1f); } packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +38 −15 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; import android.view.accessibility.AccessibilityManager; import android.view.animation.Interpolator; import android.widget.FrameLayout; import com.android.internal.logging.MetricsLogger; Loading Loading @@ -107,17 +108,20 @@ public class NotificationPanelView extends PanelView implements private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties() .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private static final FloatProperty<NotificationPanelView> SET_DARK_AMOUNT_PROPERTY = new FloatProperty<NotificationPanelView>("mDarkAmount") { new FloatProperty<NotificationPanelView>("mInterpolatedDarkAmount") { @Override public void setValue(NotificationPanelView object, float value) { object.setDarkAmount(value); object.setDarkAmount(value, object.mDarkInterpolator.getInterpolation(value)); } @Override public Float get(NotificationPanelView object) { return object.mDarkAmount; return object.mLinearDarkAmount; } }; private Interpolator mDarkInterpolator; private final PowerManager mPowerManager; private final AccessibilityManager mAccessibilityManager; Loading Loading @@ -237,7 +241,18 @@ public class NotificationPanelView extends PanelView implements private int mIndicationBottomPadding; private int mAmbientIndicationBottomPadding; private boolean mIsFullWidth; private float mDarkAmount; /** * Current dark amount that follows regular interpolation curve of animation. */ private float mInterpolatedDarkAmount; /** * Dark amount that animates from 0 to 1 or vice-versa in linear manner, even if the * interpolation curve is different. */ private float mLinearDarkAmount; private float mDarkAmountTarget; private boolean mPulsing; private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger(); Loading Loading @@ -392,7 +407,7 @@ public class NotificationPanelView extends PanelView implements false); addView(mKeyguardBottomArea, index); initBottomArea(); setDarkAmount(mDarkAmount); setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount); setKeyguardStatusViewVisibility(mStatusBarState, false, false); setKeyguardBottomAreaVisibility(mStatusBarState, false); Loading Loading @@ -506,7 +521,7 @@ public class NotificationPanelView extends PanelView implements getExpandedFraction(), totalHeight, mKeyguardStatusView.getHeight(), mDarkAmount, mInterpolatedDarkAmount, mStatusBar.isKeyguardCurrentlySecure(), mPulsing, mBouncerTop); Loading Loading @@ -1917,7 +1932,7 @@ public class NotificationPanelView extends PanelView implements if (view == null && mQsExpanded) { return; } if (needsAnimation && mDarkAmount == 0) { if (needsAnimation && mInterpolatedDarkAmount == 0) { mAnimateNextPositionUpdate = true; } ExpandableView firstChildNotGone = mNotificationStackScroller.getFirstChildNotGone(); Loading Loading @@ -2727,20 +2742,28 @@ public class NotificationPanelView extends PanelView implements } mDarkAmountTarget = darkAmount; if (animate) { if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) { mDarkInterpolator = dozing ? Interpolators.FAST_OUT_SLOW_IN : Interpolators.TOUCH_RESPONSE_REVERSE; } mNotificationStackScroller.notifyDarkAnimationStart(dozing); mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount); mDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); mDarkAnimator.setInterpolator(Interpolators.LINEAR); mDarkAnimator.setDuration(mNotificationStackScroller.getDarkAnimationDuration(dozing)); mDarkAnimator.start(); } else { setDarkAmount(darkAmount); setDarkAmount(darkAmount, darkAmount); } } private void setDarkAmount(float amount) { mDarkAmount = amount; mKeyguardStatusView.setDarkAmount(mDarkAmount); mKeyguardBottomArea.setDarkAmount(mDarkAmount); private void setDarkAmount(float linearAmount, float amount) { mInterpolatedDarkAmount = amount; mLinearDarkAmount = linearAmount; mKeyguardStatusView.setDarkAmount(mInterpolatedDarkAmount); mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount); positionClockAndNotifications(); mNotificationStackScroller.setDarkAmount(linearAmount, mInterpolatedDarkAmount); } public void setPulsing(boolean pulsing) { Loading @@ -2765,7 +2788,7 @@ public class NotificationPanelView extends PanelView implements public void dozeTimeTick() { mKeyguardStatusView.dozeTimeTick(); mKeyguardBottomArea.dozeTimeTick(); if (mDarkAmount > 0) { if (mInterpolatedDarkAmount > 0) { positionClockAndNotifications(); } } Loading packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +51 −62 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; Loading @@ -46,11 +45,9 @@ import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.support.v4.graphics.ColorUtils; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; import android.util.MathUtils; import android.util.Pair; import android.util.Property; import android.view.ContextThemeWrapper; import android.view.InputDevice; import android.view.MotionEvent; Loading Loading @@ -375,25 +372,22 @@ public class NotificationStackScrollLayout extends ViewGroup private boolean mScrollable; private View mForcedScroll; private View mNeedingPulseAnimation; private float mDarkAmount = 0f; /** * @see #setDarkAmount(float, float) */ private float mInterpolatedDarkAmount = 0f; /** * @see #setDarkAmount(float, float) */ private float mLinearDarkAmount = 0f; /** * How fast the background scales in the X direction as a factor of the Y expansion. */ private float mBackgroundXFactor = 1f; private static final Property<NotificationStackScrollLayout, Float> DARK_AMOUNT = new FloatProperty<NotificationStackScrollLayout>("darkAmount") { @Override public void setValue(NotificationStackScrollLayout object, float value) { object.setDarkAmount(value); } @Override public Float get(NotificationStackScrollLayout object) { return object.getDarkAmount(); } }; private ObjectAnimator mDarkAmountAnimator; private boolean mUsingLightTheme; private boolean mQsExpanded; private boolean mForwardScrollable; Loading Loading @@ -424,6 +418,8 @@ public class NotificationStackScrollLayout extends ViewGroup private NotificationIconAreaController mIconAreaController; private float mVerticalPanelTranslation; private Interpolator mDarkXInterpolator = Interpolators.FAST_OUT_SLOW_IN; public NotificationStackScrollLayout(Context context) { this(context, null); } Loading Loading @@ -558,16 +554,16 @@ public class NotificationStackScrollLayout extends ViewGroup canvas.drawRect(darkLeft, darkTop, darkRight, darkBottom, mBackgroundPaint); } } else { float inverseDark = 1 - mDarkAmount; float yProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(inverseDark); float xProgress = Interpolators.FAST_OUT_SLOW_IN .getInterpolation(inverseDark * mBackgroundXFactor); float yProgress = 1 - mInterpolatedDarkAmount; float xProgress = mDarkXInterpolator.getInterpolation( (1 - mLinearDarkAmount) * mBackgroundXFactor); mBackgroundAnimationRect.set( (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress), (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress), (int) MathUtils.lerp(darkRight, lockScreenRight, xProgress), (int) MathUtils.lerp(darkBottom, lockScreenBottom, yProgress)); if (!mAmbientState.isDark() || mFirstVisibleBackgroundChild != null) { canvas.drawRoundRect(mBackgroundAnimationRect.left, mBackgroundAnimationRect.top, mBackgroundAnimationRect.right, mBackgroundAnimationRect.bottom, Loading @@ -585,14 +581,15 @@ public class NotificationStackScrollLayout extends ViewGroup float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount); alpha *= 1f - mDarkAmount; alpha *= 1f - mInterpolatedDarkAmount; // We need to manually blend in the background color. int scrimColor = mScrimController.getBackgroundColor(); int awakeColor = ColorUtils.blendARGB(scrimColor, mBgColor, alpha); // Interpolate between semi-transparent notification panel background color // and white AOD separator. float colorInterpolation = Interpolators.DECELERATE_QUINT.getInterpolation(mDarkAmount); float colorInterpolation = Interpolators.DECELERATE_QUINT.getInterpolation( mInterpolatedDarkAmount); int color = ColorUtils.blendARGB(awakeColor, Color.WHITE, colorInterpolation); if (mCachedBackgroundColor != color) { Loading Loading @@ -736,7 +733,8 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateAlgorithmHeightAndPadding() { mTopPadding = (int) MathUtils.lerp(mRegularTopPadding, mDarkTopPadding, mDarkAmount); mTopPadding = (int) MathUtils.lerp(mRegularTopPadding, mDarkTopPadding, mInterpolatedDarkAmount); mAmbientState.setLayoutHeight(getLayoutHeight()); updateAlgorithmLayoutMinHeight(); mAmbientState.setTopPadding(mTopPadding); Loading Loading @@ -961,7 +959,7 @@ public class NotificationStackScrollLayout extends ViewGroup } public void updateClipping() { boolean animatingClipping = mDarkAmount > 0 && mDarkAmount < 1; boolean animatingClipping = mInterpolatedDarkAmount > 0 && mInterpolatedDarkAmount < 1; boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode && !mHeadsUpAnimatingAway; if (mIsClipped != clipped) { Loading Loading @@ -2421,7 +2419,7 @@ public class NotificationStackScrollLayout extends ViewGroup return; } final boolean awake = mDarkAmount != 0 || mAmbientState.isDark(); final boolean awake = mInterpolatedDarkAmount != 0 || mAmbientState.isDark(); mScrimController.setExcludedBackgroundArea( mFadingOut || mParentNotFullyVisible || awake || mIsClipped ? null : mCurrentBounds); Loading Loading @@ -3414,7 +3412,6 @@ public class NotificationStackScrollLayout extends ViewGroup .animateY(mShelf)); ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex; mAnimationEvents.add(ev); startDarkAmountAnimation(); } mDarkNeedsAnimation = false; } Loading Loading @@ -3992,9 +3989,6 @@ public class NotificationStackScrollLayout extends ViewGroup mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation); mNeedsAnimation = true; } else { if (mDarkAmountAnimator != null) { mDarkAmountAnimator.cancel(); } setDarkAmount(dark ? 1f : 0f); updateBackground(); } Loading @@ -4005,7 +3999,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updatePanelTranslation() { setTranslationX(mVerticalPanelTranslation + mAntiBurnInOffsetX * mDarkAmount); setTranslationX(mVerticalPanelTranslation + mAntiBurnInOffsetX * mInterpolatedDarkAmount); } public void setVerticalPanelTranslation(float verticalPanelTranslation) { Loading @@ -4024,9 +4018,22 @@ public class NotificationStackScrollLayout extends ViewGroup } private void setDarkAmount(float darkAmount) { mDarkAmount = darkAmount; setDarkAmount(darkAmount, darkAmount); } /** * Sets the current dark amount. * * @param linearDarkAmount The dark amount that follows linear interpoloation in the animation, * i.e. animates from 0 to 1 or vice-versa in a linear manner. * @param interpolatedDarkAmount The dark amount that follows the actual interpolation of the * animation curve. */ public void setDarkAmount(float linearDarkAmount, float interpolatedDarkAmount) { mLinearDarkAmount = linearDarkAmount; mInterpolatedDarkAmount = interpolatedDarkAmount; boolean wasFullyDark = mAmbientState.isFullyDark(); mAmbientState.setDarkAmount(darkAmount); mAmbientState.setDarkAmount(interpolatedDarkAmount); boolean nowFullyDark = mAmbientState.isFullyDark(); if (nowFullyDark != wasFullyDark) { updateContentHeight(); Loading @@ -4044,42 +4051,24 @@ public class NotificationStackScrollLayout extends ViewGroup requestChildrenUpdate(); } public float getDarkAmount() { return mDarkAmount; public void notifyDarkAnimationStart(boolean dark) { // We only swap the scaling factor if we're fully dark or fully awake to avoid // interpolation issues when playing with the power button. if (mInterpolatedDarkAmount == 0 || mInterpolatedDarkAmount == 1) { mBackgroundXFactor = dark ? 1.8f : 1.5f; mDarkXInterpolator = dark ? Interpolators.FAST_OUT_SLOW_IN_REVERSE : Interpolators.FAST_OUT_SLOW_IN; } /** * Cancel any previous dark animations - to avoid race conditions - and creates a new one. * This function also sets {@code mBackgroundXFactor} based on the current {@code mDarkAmount}. */ private void startDarkAmountAnimation() { boolean dark = mAmbientState.isDark(); if (mDarkAmountAnimator != null) { mDarkAmountAnimator.cancel(); } public long getDarkAnimationDuration(boolean dark) { long duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP; // Longer animation when sleeping with more than 1 notification if (dark && getNotGoneChildCount() > 2) { duration *= 1.2f; } mDarkAmountAnimator = ObjectAnimator.ofFloat(this, DARK_AMOUNT, mDarkAmount, dark ? 1f : 0); // We only swap the scaling factor if we're fully dark or fully awake to avoid // interpolation issues when playing with the power button. if (mDarkAmount == 0 || mDarkAmount == 1) { mBackgroundXFactor = dark ? 2.5f : 1.5f; } mDarkAmountAnimator.setDuration(duration); mDarkAmountAnimator.setInterpolator(Interpolators.LINEAR); mDarkAmountAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mDarkAmountAnimator = null; } }); mDarkAmountAnimator.start(); return duration; } private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) { Loading Loading
packages/SystemUI/src/com/android/systemui/Interpolators.java +14 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,13 @@ import com.android.systemui.statusbar.stack.HeadsUpAppearInterpolator; */ public class Interpolators { public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f); /** * Like {@link #FAST_OUT_SLOW_IN}, but used in case the animation is played in reverse (i.e. t * goes from 1 to 0 instead of 0 to 1). */ public static final Interpolator FAST_OUT_SLOW_IN_REVERSE = new PathInterpolator(0.8f, 0f, 0.6f, 1f); public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f); public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); Loading @@ -51,4 +58,11 @@ public class Interpolators { */ public static final Interpolator TOUCH_RESPONSE = new PathInterpolator(0.3f, 0f, 0.1f, 1f); /** * Like {@link #TOUCH_RESPONSE}, but used in case the animation is played in reverse (i.e. t * goes from 1 to 0 instead of 0 to 1). */ public static final Interpolator TOUCH_RESPONSE_REVERSE = new PathInterpolator(0.9f, 0f, 0.7f, 1f); }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +38 −15 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; import android.view.accessibility.AccessibilityManager; import android.view.animation.Interpolator; import android.widget.FrameLayout; import com.android.internal.logging.MetricsLogger; Loading Loading @@ -107,17 +108,20 @@ public class NotificationPanelView extends PanelView implements private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties() .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private static final FloatProperty<NotificationPanelView> SET_DARK_AMOUNT_PROPERTY = new FloatProperty<NotificationPanelView>("mDarkAmount") { new FloatProperty<NotificationPanelView>("mInterpolatedDarkAmount") { @Override public void setValue(NotificationPanelView object, float value) { object.setDarkAmount(value); object.setDarkAmount(value, object.mDarkInterpolator.getInterpolation(value)); } @Override public Float get(NotificationPanelView object) { return object.mDarkAmount; return object.mLinearDarkAmount; } }; private Interpolator mDarkInterpolator; private final PowerManager mPowerManager; private final AccessibilityManager mAccessibilityManager; Loading Loading @@ -237,7 +241,18 @@ public class NotificationPanelView extends PanelView implements private int mIndicationBottomPadding; private int mAmbientIndicationBottomPadding; private boolean mIsFullWidth; private float mDarkAmount; /** * Current dark amount that follows regular interpolation curve of animation. */ private float mInterpolatedDarkAmount; /** * Dark amount that animates from 0 to 1 or vice-versa in linear manner, even if the * interpolation curve is different. */ private float mLinearDarkAmount; private float mDarkAmountTarget; private boolean mPulsing; private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger(); Loading Loading @@ -392,7 +407,7 @@ public class NotificationPanelView extends PanelView implements false); addView(mKeyguardBottomArea, index); initBottomArea(); setDarkAmount(mDarkAmount); setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount); setKeyguardStatusViewVisibility(mStatusBarState, false, false); setKeyguardBottomAreaVisibility(mStatusBarState, false); Loading Loading @@ -506,7 +521,7 @@ public class NotificationPanelView extends PanelView implements getExpandedFraction(), totalHeight, mKeyguardStatusView.getHeight(), mDarkAmount, mInterpolatedDarkAmount, mStatusBar.isKeyguardCurrentlySecure(), mPulsing, mBouncerTop); Loading Loading @@ -1917,7 +1932,7 @@ public class NotificationPanelView extends PanelView implements if (view == null && mQsExpanded) { return; } if (needsAnimation && mDarkAmount == 0) { if (needsAnimation && mInterpolatedDarkAmount == 0) { mAnimateNextPositionUpdate = true; } ExpandableView firstChildNotGone = mNotificationStackScroller.getFirstChildNotGone(); Loading Loading @@ -2727,20 +2742,28 @@ public class NotificationPanelView extends PanelView implements } mDarkAmountTarget = darkAmount; if (animate) { if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) { mDarkInterpolator = dozing ? Interpolators.FAST_OUT_SLOW_IN : Interpolators.TOUCH_RESPONSE_REVERSE; } mNotificationStackScroller.notifyDarkAnimationStart(dozing); mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount); mDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); mDarkAnimator.setInterpolator(Interpolators.LINEAR); mDarkAnimator.setDuration(mNotificationStackScroller.getDarkAnimationDuration(dozing)); mDarkAnimator.start(); } else { setDarkAmount(darkAmount); setDarkAmount(darkAmount, darkAmount); } } private void setDarkAmount(float amount) { mDarkAmount = amount; mKeyguardStatusView.setDarkAmount(mDarkAmount); mKeyguardBottomArea.setDarkAmount(mDarkAmount); private void setDarkAmount(float linearAmount, float amount) { mInterpolatedDarkAmount = amount; mLinearDarkAmount = linearAmount; mKeyguardStatusView.setDarkAmount(mInterpolatedDarkAmount); mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount); positionClockAndNotifications(); mNotificationStackScroller.setDarkAmount(linearAmount, mInterpolatedDarkAmount); } public void setPulsing(boolean pulsing) { Loading @@ -2765,7 +2788,7 @@ public class NotificationPanelView extends PanelView implements public void dozeTimeTick() { mKeyguardStatusView.dozeTimeTick(); mKeyguardBottomArea.dozeTimeTick(); if (mDarkAmount > 0) { if (mInterpolatedDarkAmount > 0) { positionClockAndNotifications(); } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +51 −62 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; Loading @@ -46,11 +45,9 @@ import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.support.v4.graphics.ColorUtils; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; import android.util.MathUtils; import android.util.Pair; import android.util.Property; import android.view.ContextThemeWrapper; import android.view.InputDevice; import android.view.MotionEvent; Loading Loading @@ -375,25 +372,22 @@ public class NotificationStackScrollLayout extends ViewGroup private boolean mScrollable; private View mForcedScroll; private View mNeedingPulseAnimation; private float mDarkAmount = 0f; /** * @see #setDarkAmount(float, float) */ private float mInterpolatedDarkAmount = 0f; /** * @see #setDarkAmount(float, float) */ private float mLinearDarkAmount = 0f; /** * How fast the background scales in the X direction as a factor of the Y expansion. */ private float mBackgroundXFactor = 1f; private static final Property<NotificationStackScrollLayout, Float> DARK_AMOUNT = new FloatProperty<NotificationStackScrollLayout>("darkAmount") { @Override public void setValue(NotificationStackScrollLayout object, float value) { object.setDarkAmount(value); } @Override public Float get(NotificationStackScrollLayout object) { return object.getDarkAmount(); } }; private ObjectAnimator mDarkAmountAnimator; private boolean mUsingLightTheme; private boolean mQsExpanded; private boolean mForwardScrollable; Loading Loading @@ -424,6 +418,8 @@ public class NotificationStackScrollLayout extends ViewGroup private NotificationIconAreaController mIconAreaController; private float mVerticalPanelTranslation; private Interpolator mDarkXInterpolator = Interpolators.FAST_OUT_SLOW_IN; public NotificationStackScrollLayout(Context context) { this(context, null); } Loading Loading @@ -558,16 +554,16 @@ public class NotificationStackScrollLayout extends ViewGroup canvas.drawRect(darkLeft, darkTop, darkRight, darkBottom, mBackgroundPaint); } } else { float inverseDark = 1 - mDarkAmount; float yProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(inverseDark); float xProgress = Interpolators.FAST_OUT_SLOW_IN .getInterpolation(inverseDark * mBackgroundXFactor); float yProgress = 1 - mInterpolatedDarkAmount; float xProgress = mDarkXInterpolator.getInterpolation( (1 - mLinearDarkAmount) * mBackgroundXFactor); mBackgroundAnimationRect.set( (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress), (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress), (int) MathUtils.lerp(darkRight, lockScreenRight, xProgress), (int) MathUtils.lerp(darkBottom, lockScreenBottom, yProgress)); if (!mAmbientState.isDark() || mFirstVisibleBackgroundChild != null) { canvas.drawRoundRect(mBackgroundAnimationRect.left, mBackgroundAnimationRect.top, mBackgroundAnimationRect.right, mBackgroundAnimationRect.bottom, Loading @@ -585,14 +581,15 @@ public class NotificationStackScrollLayout extends ViewGroup float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount); alpha *= 1f - mDarkAmount; alpha *= 1f - mInterpolatedDarkAmount; // We need to manually blend in the background color. int scrimColor = mScrimController.getBackgroundColor(); int awakeColor = ColorUtils.blendARGB(scrimColor, mBgColor, alpha); // Interpolate between semi-transparent notification panel background color // and white AOD separator. float colorInterpolation = Interpolators.DECELERATE_QUINT.getInterpolation(mDarkAmount); float colorInterpolation = Interpolators.DECELERATE_QUINT.getInterpolation( mInterpolatedDarkAmount); int color = ColorUtils.blendARGB(awakeColor, Color.WHITE, colorInterpolation); if (mCachedBackgroundColor != color) { Loading Loading @@ -736,7 +733,8 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateAlgorithmHeightAndPadding() { mTopPadding = (int) MathUtils.lerp(mRegularTopPadding, mDarkTopPadding, mDarkAmount); mTopPadding = (int) MathUtils.lerp(mRegularTopPadding, mDarkTopPadding, mInterpolatedDarkAmount); mAmbientState.setLayoutHeight(getLayoutHeight()); updateAlgorithmLayoutMinHeight(); mAmbientState.setTopPadding(mTopPadding); Loading Loading @@ -961,7 +959,7 @@ public class NotificationStackScrollLayout extends ViewGroup } public void updateClipping() { boolean animatingClipping = mDarkAmount > 0 && mDarkAmount < 1; boolean animatingClipping = mInterpolatedDarkAmount > 0 && mInterpolatedDarkAmount < 1; boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode && !mHeadsUpAnimatingAway; if (mIsClipped != clipped) { Loading Loading @@ -2421,7 +2419,7 @@ public class NotificationStackScrollLayout extends ViewGroup return; } final boolean awake = mDarkAmount != 0 || mAmbientState.isDark(); final boolean awake = mInterpolatedDarkAmount != 0 || mAmbientState.isDark(); mScrimController.setExcludedBackgroundArea( mFadingOut || mParentNotFullyVisible || awake || mIsClipped ? null : mCurrentBounds); Loading Loading @@ -3414,7 +3412,6 @@ public class NotificationStackScrollLayout extends ViewGroup .animateY(mShelf)); ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex; mAnimationEvents.add(ev); startDarkAmountAnimation(); } mDarkNeedsAnimation = false; } Loading Loading @@ -3992,9 +3989,6 @@ public class NotificationStackScrollLayout extends ViewGroup mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation); mNeedsAnimation = true; } else { if (mDarkAmountAnimator != null) { mDarkAmountAnimator.cancel(); } setDarkAmount(dark ? 1f : 0f); updateBackground(); } Loading @@ -4005,7 +3999,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updatePanelTranslation() { setTranslationX(mVerticalPanelTranslation + mAntiBurnInOffsetX * mDarkAmount); setTranslationX(mVerticalPanelTranslation + mAntiBurnInOffsetX * mInterpolatedDarkAmount); } public void setVerticalPanelTranslation(float verticalPanelTranslation) { Loading @@ -4024,9 +4018,22 @@ public class NotificationStackScrollLayout extends ViewGroup } private void setDarkAmount(float darkAmount) { mDarkAmount = darkAmount; setDarkAmount(darkAmount, darkAmount); } /** * Sets the current dark amount. * * @param linearDarkAmount The dark amount that follows linear interpoloation in the animation, * i.e. animates from 0 to 1 or vice-versa in a linear manner. * @param interpolatedDarkAmount The dark amount that follows the actual interpolation of the * animation curve. */ public void setDarkAmount(float linearDarkAmount, float interpolatedDarkAmount) { mLinearDarkAmount = linearDarkAmount; mInterpolatedDarkAmount = interpolatedDarkAmount; boolean wasFullyDark = mAmbientState.isFullyDark(); mAmbientState.setDarkAmount(darkAmount); mAmbientState.setDarkAmount(interpolatedDarkAmount); boolean nowFullyDark = mAmbientState.isFullyDark(); if (nowFullyDark != wasFullyDark) { updateContentHeight(); Loading @@ -4044,42 +4051,24 @@ public class NotificationStackScrollLayout extends ViewGroup requestChildrenUpdate(); } public float getDarkAmount() { return mDarkAmount; public void notifyDarkAnimationStart(boolean dark) { // We only swap the scaling factor if we're fully dark or fully awake to avoid // interpolation issues when playing with the power button. if (mInterpolatedDarkAmount == 0 || mInterpolatedDarkAmount == 1) { mBackgroundXFactor = dark ? 1.8f : 1.5f; mDarkXInterpolator = dark ? Interpolators.FAST_OUT_SLOW_IN_REVERSE : Interpolators.FAST_OUT_SLOW_IN; } /** * Cancel any previous dark animations - to avoid race conditions - and creates a new one. * This function also sets {@code mBackgroundXFactor} based on the current {@code mDarkAmount}. */ private void startDarkAmountAnimation() { boolean dark = mAmbientState.isDark(); if (mDarkAmountAnimator != null) { mDarkAmountAnimator.cancel(); } public long getDarkAnimationDuration(boolean dark) { long duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP; // Longer animation when sleeping with more than 1 notification if (dark && getNotGoneChildCount() > 2) { duration *= 1.2f; } mDarkAmountAnimator = ObjectAnimator.ofFloat(this, DARK_AMOUNT, mDarkAmount, dark ? 1f : 0); // We only swap the scaling factor if we're fully dark or fully awake to avoid // interpolation issues when playing with the power button. if (mDarkAmount == 0 || mDarkAmount == 1) { mBackgroundXFactor = dark ? 2.5f : 1.5f; } mDarkAmountAnimator.setDuration(duration); mDarkAmountAnimator.setInterpolator(Interpolators.LINEAR); mDarkAmountAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mDarkAmountAnimator = null; } }); mDarkAmountAnimator.start(); return duration; } private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) { Loading