summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java76
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java12
6 files changed, 141 insertions, 33 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
index bddd3e6158c1..758fb7a9971e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
@@ -23,6 +23,7 @@ import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.notification.NotificationUtils;
/**
* Utility class to calculate general fling animation when the finger is released.
@@ -30,28 +31,63 @@ import com.android.systemui.Interpolators;
public class FlingAnimationUtils {
private static final float LINEAR_OUT_SLOW_IN_X2 = 0.35f;
+ private static final float LINEAR_OUT_SLOW_IN_X2_MAX = 0.68f;
private static final float LINEAR_OUT_FASTER_IN_X2 = 0.5f;
private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.4f;
private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 0.5f;
private static final float MIN_VELOCITY_DP_PER_SECOND = 250;
private static final float HIGH_VELOCITY_DP_PER_SECOND = 3000;
- /**
- * Crazy math. http://en.wikipedia.org/wiki/B%C3%A9zier_curve
- */
- private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 1.0f / LINEAR_OUT_SLOW_IN_X2;
-
- private Interpolator mLinearOutSlowIn;
+ private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 0.75f;
+ private final float mSpeedUpFactor;
+ private final float mY2;
private float mMinVelocityPxPerSecond;
private float mMaxLengthSeconds;
private float mHighVelocityPxPerSecond;
+ private float mLinearOutSlowInX2;
private AnimatorProperties mAnimatorProperties = new AnimatorProperties();
+ private PathInterpolator mInterpolator;
+ private float mCachedStartGradient = -1;
+ private float mCachedVelocityFactor = -1;
public FlingAnimationUtils(Context ctx, float maxLengthSeconds) {
+ this(ctx, maxLengthSeconds, 0.0f);
+ }
+
+ /**
+ * @param maxLengthSeconds the longest duration an animation can become in seconds
+ * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards
+ * the end of the animation. 0 means it's at the beginning and no
+ * acceleration will take place.
+ */
+ public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor) {
+ this(ctx, maxLengthSeconds, speedUpFactor, -1.0f, 1.0f);
+ }
+
+ /**
+ * @param maxLengthSeconds the longest duration an animation can become in seconds
+ * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards
+ * the end of the animation. 0 means it's at the beginning and no
+ * acceleration will take place.
+ * @param x2 the x value to take for the second point of the bezier spline. If a value below 0
+ * is provided, the value is automatically calculated.
+ * @param y2 the y value to take for the second point of the bezier spline
+ */
+ public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor, float x2,
+ float y2) {
mMaxLengthSeconds = maxLengthSeconds;
- mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_X2, 1);
+ mSpeedUpFactor = speedUpFactor;
+ if (x2 < 0) {
+ mLinearOutSlowInX2 = NotificationUtils.interpolate(LINEAR_OUT_SLOW_IN_X2,
+ LINEAR_OUT_SLOW_IN_X2_MAX,
+ mSpeedUpFactor);
+ } else {
+ mLinearOutSlowInX2 = x2;
+ }
+ mY2 = y2;
+
mMinVelocityPxPerSecond
= MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density;
mHighVelocityPxPerSecond
@@ -129,9 +165,14 @@ public class FlingAnimationUtils {
* Math.sqrt(Math.abs(endValue - currValue) / maxDistance));
float diff = Math.abs(endValue - currValue);
float velAbs = Math.abs(velocity);
- float durationSeconds = LINEAR_OUT_SLOW_IN_START_GRADIENT * diff / velAbs;
+ float velocityFactor = mSpeedUpFactor == 0.0f
+ ? 1.0f : Math.min(velAbs / HIGH_VELOCITY_DP_PER_SECOND, 1.0f);
+ float startGradient = NotificationUtils.interpolate(LINEAR_OUT_SLOW_IN_START_GRADIENT,
+ mY2 / mLinearOutSlowInX2, velocityFactor);
+ float durationSeconds = startGradient * diff / velAbs;
+ Interpolator slowInInterpolator = getInterpolator(startGradient, velocityFactor);
if (durationSeconds <= maxLengthSeconds) {
- mAnimatorProperties.interpolator = mLinearOutSlowIn;
+ mAnimatorProperties.interpolator = slowInInterpolator;
} else if (velAbs >= mMinVelocityPxPerSecond) {
// Cross fade between fast-out-slow-in and linear interpolator with current velocity.
@@ -139,7 +180,7 @@ public class FlingAnimationUtils {
VelocityInterpolator velocityInterpolator
= new VelocityInterpolator(durationSeconds, velAbs, diff);
InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
- velocityInterpolator, mLinearOutSlowIn, mLinearOutSlowIn);
+ velocityInterpolator, slowInInterpolator, Interpolators.LINEAR_OUT_SLOW_IN);
mAnimatorProperties.interpolator = superInterpolator;
} else {
@@ -151,6 +192,19 @@ public class FlingAnimationUtils {
return mAnimatorProperties;
}
+ private Interpolator getInterpolator(float startGradient, float velocityFactor) {
+ if (startGradient != mCachedStartGradient
+ || velocityFactor != mCachedVelocityFactor) {
+ float speedup = mSpeedUpFactor * (1.0f - velocityFactor);
+ mInterpolator = new PathInterpolator(speedup,
+ speedup * startGradient,
+ mLinearOutSlowInX2, mY2);
+ mCachedStartGradient = startGradient;
+ mCachedVelocityFactor = velocityFactor;
+ }
+ return mInterpolator;
+ }
+
/**
* Applies the interpolator and length to the animator, such that the fling animation is
* consistent with the finger motion for the case when the animation is making something
@@ -212,7 +266,7 @@ public class FlingAnimationUtils {
VelocityInterpolator velocityInterpolator
= new VelocityInterpolator(durationSeconds, velAbs, diff);
InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
- velocityInterpolator, mLinearOutFasterIn, mLinearOutSlowIn);
+ velocityInterpolator, mLinearOutFasterIn, Interpolators.LINEAR_OUT_SLOW_IN);
mAnimatorProperties.interpolator = superInterpolator;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 296c788b13d5..bc1b9fb89270 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -66,6 +66,7 @@ public class NotificationShelf extends ActivatableNotificationView {
private int mScrollFastThreshold;
private int mStatusBarState;
private float mMaxShelfEnd;
+ private int mRelativeOffset;
public NotificationShelf(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -475,9 +476,21 @@ public class NotificationShelf extends ActivatableNotificationView {
return super.shouldHideBackground() || mHideBackground;
}
- private void setOpenedAmount(float openedAmount) {
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
mCollapsedIcons.getLocationOnScreen(mTmp);
- int start = mTmp[0];
+ mRelativeOffset = mTmp[0];
+ getLocationOnScreen(mTmp);
+ mRelativeOffset -= mTmp[0];
+ }
+
+ private void setOpenedAmount(float openedAmount) {
+ if (!mAmbientState.isPanelFullWidth()) {
+ // We don't do a transformation at all, lets just assume we are fully opened
+ openedAmount = 1.0f;
+ }
+ int start = mRelativeOffset;
if (isLayoutRtl()) {
start = getWidth() - start - mCollapsedIcons.getWidth();
}
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 7f6322ae058f..82a5cc2bf415 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -210,6 +210,7 @@ public class NotificationPanelView extends PanelView implements
private NotificationGroupManager mGroupManager;
private boolean mOpening;
private int mIndicationBottomPadding;
+ private boolean mIsFullWidth;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -302,6 +303,7 @@ public class NotificationPanelView extends PanelView implements
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
+ setIsFullWidth(mNotificationStackScroller.getWidth() == getWidth());
// Update Clock Pivot
mKeyguardStatusView.setPivotX(getWidth() / 2);
@@ -340,6 +342,11 @@ public class NotificationPanelView extends PanelView implements
updateMaxHeadsUpTranslation();
}
+ private void setIsFullWidth(boolean isFullWidth) {
+ mIsFullWidth = isFullWidth;
+ mNotificationStackScroller.setIsFullWidth(isFullWidth);
+ }
+
private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
if (mQsSizeChangeAnimator != null) {
oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
@@ -736,7 +743,7 @@ public class NotificationPanelView extends PanelView implements
@Override
protected float getOpeningHeight() {
- return mNotificationStackScroller.getMinExpansionHeight();
+ return mNotificationStackScroller.getOpeningHeight();
}
@Override
@@ -2000,12 +2007,9 @@ public class NotificationPanelView extends PanelView implements
}
@Override
- protected float getCannedFlingDurationFactor() {
- if (mQsExpanded) {
- return 0.9f;
- } else {
- return 0.8f;
- }
+ protected boolean shouldUseDismissingAnimation() {
+ return mStatusBarState != StatusBarState.SHADE
+ && !mStatusBar.isKeyguardCurrentlySecure();
}
@Override
@@ -2288,7 +2292,15 @@ public class NotificationPanelView extends PanelView implements
}
mNotificationStackScroller.setExpandedHeight(expandedHeight);
updateKeyguardBottomAreaAlpha();
- setOpening(expandedHeight <= getOpeningHeight());
+ setOpening(isFullWidth() && expandedHeight < getOpeningHeight());
+ }
+
+ /**
+ * @return whether the notifications are displayed full width and don't have any margins on
+ * the side.
+ */
+ public boolean isFullWidth() {
+ return mIsFullWidth;
}
private void setOpening(boolean opening) {
@@ -2401,12 +2413,11 @@ public class NotificationPanelView extends PanelView implements
}
public boolean shouldHideNotificationIcons() {
- return !mOpening && !isFullyCollapsed();
+ return !isFullWidth() || (!mOpening && !isFullyCollapsed());
}
public boolean shouldAnimateIconHiding() {
- // TODO: handle this correctly, not completely working yet
- return mNotificationStackScroller.getTranslationX() != 0;
+ return !isFullWidth();
}
private final FragmentListener mFragmentListener = new FragmentListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 7bb075b716b7..18e394e2836a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -94,6 +94,7 @@ public abstract class PanelView extends FrameLayout {
private VelocityTrackerInterface mVelocityTracker;
private FlingAnimationUtils mFlingAnimationUtils;
private FlingAnimationUtils mFlingAnimationUtilsClosing;
+ private FlingAnimationUtils mFlingAnimationUtilsDismissing;
private FalsingManager mFalsingManager;
/**
@@ -180,8 +181,13 @@ public abstract class PanelView extends FrameLayout {
public PanelView(Context context, AttributeSet attrs) {
super(context, attrs);
- mFlingAnimationUtils = new FlingAnimationUtils(context, 0.6f);
- mFlingAnimationUtilsClosing = new FlingAnimationUtils(context, 0.4f);
+ mFlingAnimationUtils = new FlingAnimationUtils(context, 0.6f /* maxLengthSeconds */,
+ 0.6f /* speedUpFactor */);
+ mFlingAnimationUtilsClosing = new FlingAnimationUtils(context, 0.5f /* maxLengthSeconds */,
+ 0.6f /* speedUpFactor */);
+ mFlingAnimationUtilsDismissing = new FlingAnimationUtils(context,
+ 0.5f /* maxLengthSeconds */, 0.2f /* speedUpFactor */, 0.6f /* x2 */,
+ 0.84f /* y2 */);
mBounceInterpolator = new BounceInterpolator();
mFalsingManager = FalsingManager.getInstance(context);
}
@@ -700,13 +706,17 @@ public abstract class PanelView extends FrameLayout {
animator.setDuration(350);
}
} else {
- mFlingAnimationUtilsClosing.apply(animator, mExpandedHeight, target, vel, getHeight());
+ if (shouldUseDismissingAnimation()) {
+ mFlingAnimationUtilsDismissing.apply(animator, mExpandedHeight, target, vel,
+ getHeight());
+ } else {
+ mFlingAnimationUtilsClosing
+ .apply(animator, mExpandedHeight, target, vel, getHeight());
+ }
// Make it shorter if we run a canned animation
if (vel == 0) {
- animator.setDuration((long)
- (animator.getDuration() * getCannedFlingDurationFactor()
- / collapseSpeedUpFactor));
+ animator.setDuration((long) (animator.getDuration() / collapseSpeedUpFactor));
}
}
animator.addListener(new AnimatorListenerAdapter() {
@@ -733,6 +743,8 @@ public abstract class PanelView extends FrameLayout {
animator.start();
}
+ protected abstract boolean shouldUseDismissingAnimation();
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -1114,9 +1126,6 @@ public abstract class PanelView extends FrameLayout {
public abstract void resetViews();
protected abstract float getPeekHeight();
-
- protected abstract float getCannedFlingDurationFactor();
-
/**
* @return whether "Clear all" button will be visible when the panel is fully expanded
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index e1ff29703da7..fe83dc47649e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -58,6 +58,7 @@ public class AmbientState {
private float mExpandingVelocity;
private boolean mPanelTracking;
private boolean mExpansionChanging;
+ private boolean mPanelFullWidth;
public AmbientState(Context context) {
reload(context);
@@ -287,4 +288,12 @@ public class AmbientState {
public boolean isPanelTracking() {
return mPanelTracking;
}
+
+ public boolean isPanelFullWidth() {
+ return mPanelFullWidth;
+ }
+
+ public void setPanelFullWidth(boolean panelFullWidth) {
+ mPanelFullWidth = panelFullWidth;
+ }
}
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 e7c2507dbf18..06cd769ed73d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -4012,6 +4012,18 @@ public class NotificationStackScrollLayout extends ViewGroup
mAmbientState.setExpandingVelocity(expandingVelocity);
}
+ public float getOpeningHeight() {
+ if (mEmptyShadeView.getVisibility() == GONE) {
+ return getMinExpansionHeight();
+ } else {
+ return getAppearEndPosition();
+ }
+ }
+
+ public void setIsFullWidth(boolean isFullWidth) {
+ mAmbientState.setPanelFullWidth(isFullWidth);
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/