diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index b2200910a2823..a1e5b0e6e5e20 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -138,7 +138,7 @@ - 9dp + 42dp 32dp @@ -497,9 +497,6 @@ device. --> 75dp - - 100dp - 75dp diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index d45c427d3082f..458e133d765fd 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -24,6 +24,8 @@ + + @@ -34,6 +36,8 @@ + + @@ -43,6 +47,8 @@ + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 6364f5b63e881..44136c58875d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -58,7 +58,7 @@ public class NotificationShelf extends ActivatableNotificationView implements = SystemProperties.getBoolean("debug.icon_scroll_animations", true); private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag; private static final String TAG = "NotificationShelf"; - private static final long SHELF_IN_TRANSLATION_DURATION = 220; + private static final long SHELF_IN_TRANSLATION_DURATION = 200; private ViewInvertHelper mViewInvertHelper; private boolean mDark; @@ -157,14 +157,18 @@ public class NotificationShelf extends ActivatableNotificationView implements public void fadeInTranslating() { float translation = mShelfIcons.getTranslationY(); - mShelfIcons.setTranslationY(translation + mShelfAppearTranslation); + mShelfIcons.setTranslationY(translation - mShelfAppearTranslation); mShelfIcons.setAlpha(0); mShelfIcons.animate() - .alpha(1) - .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN) + .setInterpolator(Interpolators.DECELERATE_QUINT) .translationY(translation) .setDuration(SHELF_IN_TRANSLATION_DURATION) .start(); + mShelfIcons.animate() + .alpha(1) + .setInterpolator(Interpolators.LINEAR) + .setDuration(SHELF_IN_TRANSLATION_DURATION) + .start(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java index d7b211f90be51..75b41ca3e162e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java @@ -20,25 +20,30 @@ import android.util.FloatProperty; import android.util.Property; import android.view.View; -import com.android.systemui.statusbar.stack.AnimationProperties; +import com.android.systemui.R; import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.function.Function; /** * An animatable property of a view. Used with {@link PropertyAnimator} */ -public interface AnimatableProperty { - int getAnimationStartTag(); +public abstract class AnimatableProperty { - int getAnimationEndTag(); + public static final AnimatableProperty X = AnimatableProperty.from(View.X, + R.id.x_animator_tag, R.id.x_animator_tag_start_value, R.id.x_animator_tag_end_value); + public static final AnimatableProperty Y = AnimatableProperty.from(View.Y, + R.id.y_animator_tag, R.id.y_animator_tag_start_value, R.id.y_animator_tag_end_value); - int getAnimatorTag(); + public abstract int getAnimationStartTag(); - Property getProperty(); + public abstract int getAnimationEndTag(); - static AnimatableProperty from(String name, BiConsumer setter, + public abstract int getAnimatorTag(); + + public abstract Property getProperty(); + + public static AnimatableProperty from(String name, BiConsumer setter, Function getter, int animatorTag, int startValueTag, int endValueTag) { Property property = new FloatProperty(name) { @@ -74,4 +79,29 @@ public interface AnimatableProperty { } }; } + + public static AnimatableProperty from(Property property, + int animatorTag, int startValueTag, int endValueTag) { + return new AnimatableProperty() { + @Override + public int getAnimationStartTag() { + return startValueTag; + } + + @Override + public int getAnimationEndTag() { + return endValueTag; + } + + @Override + public int getAnimatorTag() { + return animatorTag; + } + + @Override + public Property getProperty() { + return property; + } + }; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java index 92dcc9e3cf9f8..2efcd16912497 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java @@ -24,6 +24,7 @@ import android.util.Property; import android.view.View; import android.view.animation.Interpolator; +import com.android.keyguard.KeyguardStatusView; import com.android.systemui.Interpolators; import com.android.systemui.statusbar.stack.AnimationFilter; import com.android.systemui.statusbar.stack.AnimationProperties; @@ -115,4 +116,7 @@ public class PropertyAnimator { view.setTag(animationEndTag, newEndValue); } + public static boolean isAnimating(T view, AnimatableProperty property) { + return view.getTag(property.getAnimatorTag()) != null; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index d9a55c59d21ce..042e4ff16d3a7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -20,8 +20,8 @@ import static com.android.systemui.statusbar.notification.NotificationUtils.inte import android.content.res.Resources; import android.util.MathUtils; -import com.android.keyguard.KeyguardStatusView; +import com.android.keyguard.KeyguardStatusView; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -46,12 +46,6 @@ public class KeyguardClockPositionAlgorithm { */ private int mClockNotificationsMargin; - /** - * Current height of {@link NotificationPanelView}, considering how much the - * user collapsed it. - */ - private float mExpandedHeight; - /** * Height of the parent view - display size in px. */ @@ -84,9 +78,9 @@ public class KeyguardClockPositionAlgorithm { private int mContainerTopPadding; /** - * @see NotificationPanelView#getMaxPanelHeight() + * @see NotificationPanelView#getExpandedFraction() */ - private float mMaxPanelHeight; + private float mPanelExpansion; /** * Burn-in prevention x translation. @@ -140,13 +134,13 @@ public class KeyguardClockPositionAlgorithm { } public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight, - float expandedHeight, float maxPanelHeight, int parentHeight, int keyguardStatusHeight, - float dark, boolean secure, boolean pulsing, int bouncerTop) { + float panelExpansion, int parentHeight, + int keyguardStatusHeight, float dark, boolean secure, boolean pulsing, + int bouncerTop) { mMinTopMargin = minTopMargin + mContainerTopPadding; mMaxShadeBottom = maxShadeBottom; mNotificationStackHeight = notificationStackHeight; - mExpandedHeight = expandedHeight; - mMaxPanelHeight = maxPanelHeight; + mPanelExpansion = panelExpansion; mHeight = parentHeight; mKeyguardStatusHeight = keyguardStatusHeight; mDarkAmount = dark; @@ -171,16 +165,12 @@ public class KeyguardClockPositionAlgorithm { return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin; } - public int getExpandedClockBottom() { - return getExpandedClockPosition() + mKeyguardStatusHeight; - } - /** * Vertically align the clock and the shade in the available space considering only * a percentage of the clock height defined by {@code CLOCK_HEIGHT_WEIGHT}. * @return Clock Y in pixels. */ - private int getExpandedClockPosition() { + public int getExpandedClockPosition() { final int availableHeight = mMaxShadeBottom - mMinTopMargin; final int containerCenter = mMinTopMargin + availableHeight / 2; @@ -212,8 +202,7 @@ public class KeyguardClockPositionAlgorithm { mMinTopMargin : -mKeyguardStatusHeight; // Move clock up while collapsing the shade - float shadeExpansion = mExpandedHeight / mMaxPanelHeight; - shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(shadeExpansion); + float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(mPanelExpansion); final float clockY = MathUtils.lerp(clockYTarget, clockYRegular, shadeExpansion); return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount); 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 ca459a5fa0e4e..a0a97c5aae5f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -20,7 +20,6 @@ import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.ActivityManager; @@ -44,7 +43,6 @@ import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; -import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; @@ -69,8 +67,11 @@ import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.AnimatableProperty; +import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; +import com.android.systemui.statusbar.stack.AnimationProperties; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.stack.StackStateAnimator; @@ -101,6 +102,8 @@ public class NotificationPanelView extends PanelView implements public static final long DOZE_ANIMATION_DURATION = 700; + private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties() + .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private static final FloatProperty SET_DARK_AMOUNT_PROPERTY = new FloatProperty("mDarkAmount") { @Override @@ -122,11 +125,10 @@ public class NotificationPanelView extends PanelView implements private QS mQs; private FrameLayout mQsFrame; private KeyguardStatusView mKeyguardStatusView; - private View mReserveNotificationSpace; private View mQsNavbarScrim; protected NotificationsQuickSettingsContainer mNotificationContainerParent; protected NotificationStackScrollLayout mNotificationStackScroller; - private boolean mAnimateNextTopPaddingChange; + private boolean mAnimateNextPositionUpdate; private int mTrackingPointer; private VelocityTracker mQsVelocityTracker; @@ -173,9 +175,6 @@ public class NotificationPanelView extends PanelView implements private int mUnlockMoveDistance; private float mEmptyDragAmount; - private Animator mClockAnimator; - private int mClockAnimationTargetX = Integer.MIN_VALUE; - private int mClockAnimationTargetY = Integer.MIN_VALUE; private KeyguardClockPositionAlgorithm mClockPositionAlgorithm = new KeyguardClockPositionAlgorithm(); private KeyguardClockPositionAlgorithm.Result mClockPositionResult = @@ -183,7 +182,6 @@ public class NotificationPanelView extends PanelView implements private boolean mIsExpanding; private boolean mBlockTouches; - private int mNotificationScrimWaitDistance; // Used for two finger gesture as well as accessibility shortcut to QS. private boolean mQsExpandImmediate; private boolean mTwoFingerQsExpandPossible; @@ -310,8 +308,6 @@ public class NotificationPanelView extends PanelView implements getResources().getDimensionPixelSize(R.dimen.header_notifications_collide_distance); mUnlockMoveDistance = getResources().getDimensionPixelOffset(R.dimen.unlock_move_distance); mClockPositionAlgorithm.loadDimens(getResources()); - mNotificationScrimWaitDistance = - getResources().getDimensionPixelSize(R.dimen.notification_scrim_wait_distance); mQsFalsingThreshold = getResources().getDimensionPixelSize( R.dimen.qs_falsing_threshold); mPositionMinSideMargin = getResources().getDimensionPixelSize( @@ -461,19 +457,19 @@ public class NotificationPanelView extends PanelView implements */ private void positionClockAndNotifications() { boolean animate = mNotificationStackScroller.isAddOrRemoveAnimationPending(); + boolean animateClock = animate || mAnimateNextPositionUpdate; int stackScrollerPadding; if (mStatusBarState != StatusBarState.KEYGUARD) { stackScrollerPadding = (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight + mQsNotificationTopPadding; } else { - final int totalHeight = getHeight(); - final int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding); + int totalHeight = getHeight(); + int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding); mClockPositionAlgorithm.setup( mStatusBarMinHeight, totalHeight - bottomPadding, - calculatePanelHeightShade() - mNotificationStackScroller.getTopPadding(), - getExpandedHeight(), - getMaxPanelHeight(), + mNotificationStackScroller.getIntrinsicContentHeight(), + getExpandedFraction(), totalHeight, mKeyguardStatusView.getHeight(), mDarkAmount, @@ -481,12 +477,10 @@ public class NotificationPanelView extends PanelView implements mPulsing, mBouncerTop); mClockPositionAlgorithm.run(mClockPositionResult); - if (animate || mClockAnimator != null) { - startClockAnimation(mClockPositionResult.clockX, mClockPositionResult.clockY); - } else { - mKeyguardStatusView.setX(mClockPositionResult.clockX); - mKeyguardStatusView.setY(mClockPositionResult.clockY); - } + PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X, + mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock); + PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.Y, + mClockPositionResult.clockY, CLOCK_ANIMATION_PROPERTIES, animateClock); updateClock(); stackScrollerPadding = mClockPositionResult.stackScrollerPadding; } @@ -497,6 +491,7 @@ public class NotificationPanelView extends PanelView implements mStackScrollerMeasuringPass++; requestScrollerTopPaddingUpdate(animate); mStackScrollerMeasuringPass = 0; + mAnimateNextPositionUpdate = false; } /** @@ -558,42 +553,6 @@ public class NotificationPanelView extends PanelView implements positionClockAndNotifications(); } - private void startClockAnimation(int x, int y) { - if (mClockAnimationTargetX == x && mClockAnimationTargetY == y) { - return; - } - mClockAnimationTargetX = x; - mClockAnimationTargetY = y; - getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - getViewTreeObserver().removeOnPreDrawListener(this); - if (mClockAnimator != null) { - mClockAnimator.removeAllListeners(); - mClockAnimator.cancel(); - } - AnimatorSet set = new AnimatorSet(); - set.play(ObjectAnimator.ofFloat( - mKeyguardStatusView, View.Y, mClockAnimationTargetY)) - .with(ObjectAnimator.ofFloat( - mKeyguardStatusView, View.X, mClockAnimationTargetX)); - mClockAnimator = set; - mClockAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - mClockAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mClockAnimator = null; - mClockAnimationTargetX = Integer.MIN_VALUE; - mClockAnimationTargetY = Integer.MIN_VALUE; - } - }); - mClockAnimator.start(); - return true; - } - }); - } - private void updateClock() { if (!mKeyguardStatusViewAnimating) { mKeyguardStatusView.setAlpha(mClockPositionResult.clockAlpha); @@ -601,9 +560,9 @@ public class NotificationPanelView extends PanelView implements } public void animateToFullShade(long delay) { - mAnimateNextTopPaddingChange = true; mNotificationStackScroller.goToFullShade(delay); requestLayout(); + mAnimateNextPositionUpdate = true; } public void setQsExpansionEnabled(boolean qsExpansionEnabled) { @@ -1411,10 +1370,8 @@ public class NotificationPanelView extends PanelView implements protected void requestScrollerTopPaddingUpdate(boolean animate) { mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(), - mAnimateNextTopPaddingChange || animate, - mKeyguardShowing + animate, mKeyguardShowing && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted)); - mAnimateNextTopPaddingChange = false; } private void trackMovement(MotionEvent event) { @@ -1535,7 +1492,7 @@ public class NotificationPanelView extends PanelView implements if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) { maxHeight = calculatePanelHeightQsExpanded(); } else { - maxHeight = Math.max(calculatePanelHeightShade(), calculatePanelHeightShadeExpanded()); + maxHeight = calculatePanelHeightShade(); } maxHeight = Math.max(maxHeight, min); return maxHeight; @@ -1606,14 +1563,15 @@ public class NotificationPanelView extends PanelView implements int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin(); int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin; maxHeight += mNotificationStackScroller.getTopPaddingOverflow(); - return maxHeight; - } - private int calculatePanelHeightShadeExpanded() { - return mNotificationStackScroller.getHeight() - - mNotificationStackScroller.getEmptyBottomMargin() - - mNotificationStackScroller.getTopPadding() - + mClockPositionAlgorithm.getExpandedClockBottom(); + if (mStatusBarState == StatusBarState.KEYGUARD) { + int minKeyguardPanelBottom = mClockPositionAlgorithm.getExpandedClockPosition() + + mKeyguardStatusView.getHeight() + + mNotificationStackScroller.getIntrinsicContentHeight(); + return Math.max(maxHeight, minKeyguardPanelBottom); + } else { + return maxHeight; + } } private int calculatePanelHeightQsExpanded() { @@ -1652,7 +1610,8 @@ public class NotificationPanelView extends PanelView implements private void updateNotificationTranslucency() { float alpha = 1f; - if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp && !mHeadsUpManager.hasPinnedHeadsUp()) { + if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp && + !mHeadsUpManager.hasPinnedHeadsUp()) { alpha = getFadeoutAlpha(); } mNotificationStackScroller.setAlpha(alpha); @@ -1907,13 +1866,16 @@ public class NotificationPanelView extends PanelView implements if (view == null && mQsExpanded) { return; } + if (needsAnimation) { + mAnimateNextPositionUpdate = true; + } ExpandableView firstChildNotGone = mNotificationStackScroller.getFirstChildNotGone(); ExpandableNotificationRow firstRow = firstChildNotGone instanceof ExpandableNotificationRow ? (ExpandableNotificationRow) firstChildNotGone : null; if (firstRow != null && (view == firstRow || (firstRow.getNotificationParent() == firstRow))) { - requestScrollerTopPaddingUpdate(false); + requestScrollerTopPaddingUpdate(false /* animate */); } requestPanelHeightUpdate(); } @@ -2337,15 +2299,15 @@ public class NotificationPanelView extends PanelView implements p.setColor(Color.YELLOW); canvas.drawLine(0, calculatePanelHeightShade(), getWidth(), calculatePanelHeightShade(), p); - p.setColor(Color.GRAY); - canvas.drawLine(0, calculatePanelHeightShadeExpanded(), getWidth(), - calculatePanelHeightShadeExpanded(), p); p.setColor(Color.MAGENTA); canvas.drawLine(0, calculateQsTopPadding(), getWidth(), calculateQsTopPadding(), p); p.setColor(Color.CYAN); - canvas.drawLine(0, mNotificationStackScroller.getTopPadding(), getWidth(), + canvas.drawLine(0, mClockPositionResult.stackScrollerPadding, getWidth(), mNotificationStackScroller.getTopPadding(), p); + p.setColor(Color.GRAY); + canvas.drawLine(0, mClockPositionResult.clockY, getWidth(), + mClockPositionResult.clockY, p); } } 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 304a4997ae25f..347a4b04554b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -828,7 +828,7 @@ public abstract class PanelView extends FrameLayout { } @Override - protected void onLayout (boolean changed, int left, int top, int right, int bottom) { + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mStatusBar.onPanelLaidOut(); requestPanelHeightUpdate(); @@ -1088,13 +1088,10 @@ public abstract class PanelView extends FrameLayout { } cancelPeek(); notifyExpandingStarted(); - startUnlockHintAnimationPhase1(new Runnable() { - @Override - public void run() { - notifyExpandingFinished(); - onUnlockHintFinished(); - mHintAnimationRunning = false; - } + startUnlockHintAnimationPhase1(() -> { + notifyExpandingFinished(); + onUnlockHintFinished(); + mHintAnimationRunning = false; }); onUnlockHintStarted(); mHintAnimationRunning = true; 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 7c64811a885e0..b1c0a9605e28f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -164,6 +164,7 @@ public class NotificationStackScrollLayout extends ViewGroup private Paint mDebugPaint; private int mContentHeight; + private int mIntrinsicContentHeight; private int mCollapsedSize; private int mPaddingBetweenElements; private int mIncreasedPaddingBetweenElements; @@ -538,15 +539,16 @@ public class NotificationStackScrollLayout extends ViewGroup canvas.drawRect(darkLeft, darkTop, darkRight, darkBottom, mBackgroundPaint); } } else { - float animProgress = Interpolators.FAST_OUT_SLOW_IN - .getInterpolation(1f - mDarkAmount); - float sidePaddingsProgress = Interpolators.FAST_OUT_SLOW_IN - .getInterpolation((1f - mDarkAmount) * 2); + float inverseDark = 1 - mDarkAmount; + float yProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(inverseDark); + float xProgress = Interpolators.FAST_OUT_SLOW_IN + .getInterpolation(inverseDark * 2f); + mBackgroundAnimationRect.set( - (int) MathUtils.lerp(darkLeft, lockScreenLeft, sidePaddingsProgress), - (int) MathUtils.lerp(darkTop, lockScreenTop, animProgress), - (int) MathUtils.lerp(darkRight, lockScreenRight, sidePaddingsProgress), - (int) MathUtils.lerp(darkBottom, lockScreenBottom, animProgress)); + (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, @@ -628,8 +630,12 @@ public class NotificationStackScrollLayout extends ViewGroup } private void notifyHeightChangeListener(ExpandableView view) { + notifyHeightChangeListener(view, false /* needsAnimation */); + } + + private void notifyHeightChangeListener(ExpandableView view, boolean needsAnimation) { if (mOnHeightChangedListener != null) { - mOnHeightChangedListener.onHeightChanged(view, false /* needsAnimation */); + mOnHeightChangedListener.onHeightChanged(view, needsAnimation); } } @@ -850,7 +856,7 @@ public class NotificationStackScrollLayout extends ViewGroup mNeedsAnimation = true; } requestChildrenUpdate(); - notifyHeightChangeListener(null); + notifyHeightChangeListener(null, animate); } } @@ -915,6 +921,13 @@ public class NotificationStackScrollLayout extends ViewGroup updateClipping(); } + /** + * Return the height of the content ignoring the footer. + */ + public int getIntrinsicContentHeight() { + return mIntrinsicContentHeight; + } + public void updateClipping() { boolean animatingClipping = mDarkAmount > 0 && mDarkAmount < 1; boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode @@ -2130,8 +2143,9 @@ public class NotificationStackScrollLayout extends ViewGroup for (int i = 0; i < getChildCount(); i++) { ExpandableView expandableView = (ExpandableView) getChildAt(i); + boolean footerViewOnLockScreen = expandableView == mFooterView && onKeyguard(); if (expandableView.getVisibility() != View.GONE - && !expandableView.hasNoContentHeight()) { + && !expandableView.hasNoContentHeight() && !footerViewOnLockScreen) { boolean limitReached = maxDisplayedNotifications != -1 && numShownItems >= maxDisplayedNotifications; boolean notificationOnAmbientThatIsNotPulsing = mAmbientState.isFullyDark() @@ -2179,6 +2193,7 @@ public class NotificationStackScrollLayout extends ViewGroup } } } + mIntrinsicContentHeight = height; mContentHeight = height + mTopPadding + mBottomMargin; updateScrollability(); clampScrollPosition(); @@ -3656,7 +3671,7 @@ public class NotificationStackScrollLayout extends ViewGroup updateContentHeight(); updateScrollPositionOnExpandInBottom(view); clampScrollPosition(); - notifyHeightChangeListener(view); + notifyHeightChangeListener(view, needsAnimation); ExpandableNotificationRow row = view instanceof ExpandableNotificationRow ? (ExpandableNotificationRow) view : null; @@ -3970,6 +3985,7 @@ public class NotificationStackScrollLayout extends ViewGroup mShelf.fadeInTranslating(); } } + updateAlgorithmHeightAndPadding(); updateBackgroundDimming(); updateAntiBurnInTranslation(); requestChildrenUpdate(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java index a153140dfc3fb..f0ca3efdb2504 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.stack.AnimationFilter; import com.android.systemui.statusbar.stack.AnimationProperties; import com.android.systemui.statusbar.stack.ViewState; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -227,4 +228,13 @@ public class PropertyAnimatorTest extends SysuiTestCase { assertNotNull(animator); assertTrue(animator.getListeners().contains(mFinishListener)); } + + @Test + public void testIsAnimating() { + mAnimationFilter.reset(); + mAnimationFilter.animate(mProperty.getProperty()); + assertFalse(PropertyAnimator.isAnimating(mView, mProperty)); + PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties); + assertTrue(PropertyAnimator.isAnimating(mView, mProperty)); + } }