summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/Interpolators.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java113
3 files changed, 103 insertions, 77 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/Interpolators.java b/packages/SystemUI/src/com/android/systemui/Interpolators.java
index aeef49689517..eb704c863ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/Interpolators.java
+++ b/packages/SystemUI/src/com/android/systemui/Interpolators.java
@@ -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);
@@ -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);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7bd5fd0430c2..7e6abe95e226 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -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;
@@ -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;
@@ -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();
@@ -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);
@@ -506,7 +521,7 @@ public class NotificationPanelView extends PanelView implements
getExpandedFraction(),
totalHeight,
mKeyguardStatusView.getHeight(),
- mDarkAmount,
+ mInterpolatedDarkAmount,
mStatusBar.isKeyguardCurrentlySecure(),
mPulsing,
mBouncerTop);
@@ -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();
@@ -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) {
@@ -2765,7 +2788,7 @@ public class NotificationPanelView extends PanelView implements
public void dozeTimeTick() {
mKeyguardStatusView.dozeTimeTick();
mKeyguardBottomArea.dozeTimeTick();
- if (mDarkAmount > 0) {
+ if (mInterpolatedDarkAmount > 0) {
positionClockAndNotifications();
}
}
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 9d0d295a26ca..ff4f215b482f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -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;
@@ -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;
@@ -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;
@@ -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);
}
@@ -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,
@@ -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) {
@@ -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);
@@ -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) {
@@ -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);
@@ -3414,7 +3412,6 @@ public class NotificationStackScrollLayout extends ViewGroup
.animateY(mShelf));
ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex;
mAnimationEvents.add(ev);
- startDarkAmountAnimation();
}
mDarkNeedsAnimation = false;
}
@@ -3990,11 +3987,8 @@ public class NotificationStackScrollLayout extends ViewGroup
if (animate && mAnimationsEnabled) {
mDarkNeedsAnimation = true;
mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation);
- mNeedsAnimation = true;
+ mNeedsAnimation = true;
} else {
- if (mDarkAmountAnimator != null) {
- mDarkAmountAnimator.cancel();
- }
setDarkAmount(dark ? 1f : 0f);
updateBackground();
}
@@ -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) {
@@ -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();
@@ -4044,42 +4051,24 @@ public class NotificationStackScrollLayout extends ViewGroup
requestChildrenUpdate();
}
- public float getDarkAmount() {
- return mDarkAmount;
- }
-
- /**
- * 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 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;
}
+ }
+ 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) {