Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +91 −34 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; import com.android.systemui.statusbar.notification.stack.ViewState; import com.android.systemui.statusbar.phone.NotificationIconContainer; Loading Loading @@ -82,6 +83,9 @@ public class NotificationShelf extends ActivatableNotificationView implements private Rect mClipRect = new Rect(); private int mCutoutHeight; private int mGapHeight; private int mIndexOfFirstViewInShelf = -1; private int mIndexOfFirstViewInOverflowingSection = -1; private NotificationShelfController mController; public NotificationShelf(Context context, AttributeSet attrs) { Loading Loading @@ -159,30 +163,49 @@ public class NotificationShelf extends ActivatableNotificationView implements } /** Update the state of the shelf. */ public void updateState(AmbientState ambientState) { public void updateState(StackScrollAlgorithm.StackScrollAlgorithmState algorithmState, AmbientState ambientState) { ExpandableView lastView = ambientState.getLastVisibleBackgroundChild(); ShelfState viewState = (ShelfState) getViewState(); if (mShowNotificationShelf && lastView != null) { float maxShelfEnd = ambientState.getInnerHeight() + ambientState.getTopPadding() + ambientState.getStackTranslation(); ExpandableViewState lastViewState = lastView.getViewState(); float viewEnd = lastViewState.yTranslation + lastViewState.height; viewState.copyFrom(lastViewState); viewState.height = getIntrinsicHeight(); viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height, getFullyClosedTranslation()); viewState.zTranslation = ambientState.getBaseZHeight(); viewState.clipTopAmount = 0; viewState.alpha = 1f - ambientState.getHideAmount(); viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0; viewState.hideSensitive = false; viewState.xTranslation = getTranslationX(); viewState.hasItemsInStableShelf = lastViewState.inShelf; viewState.firstViewInShelf = algorithmState.firstViewInShelf; viewState.firstViewInOverflowSection = algorithmState.firstViewInOverflowSection; if (mNotGoneIndex != -1) { viewState.notGoneIndex = Math.min(viewState.notGoneIndex, mNotGoneIndex); } viewState.hasItemsInStableShelf = lastViewState.inShelf; viewState.hidden = !mAmbientState.isShadeExpanded() || mAmbientState.isQsCustomizerShowing(); || mAmbientState.isQsCustomizerShowing() || algorithmState.firstViewInShelf == null; final int indexOfFirstViewInShelf = algorithmState.visibleChildren.indexOf( algorithmState.firstViewInShelf); if (mAmbientState.isExpansionChanging() && algorithmState.firstViewInShelf != null && indexOfFirstViewInShelf > 0) { // Show shelf if section before it is showing. final ExpandableView viewBeforeShelf = algorithmState.visibleChildren.get( indexOfFirstViewInShelf - 1); if (viewBeforeShelf.getViewState().hidden) { viewState.hidden = true; } } final float stackEnd = ambientState.getStackY() + ambientState.getStackHeight(); viewState.yTranslation = stackEnd - viewState.height; } else { viewState.hidden = true; viewState.location = ExpandableViewState.LOCATION_GONE; Loading @@ -199,13 +222,11 @@ public class NotificationShelf extends ActivatableNotificationView implements if (!mShowNotificationShelf) { return; } mShelfIcons.resetViewStates(); float shelfStart = getTranslationY(); float numViewsInShelf = 0.0f; View lastChild = mAmbientState.getLastVisibleBackgroundChild(); mNotGoneIndex = -1; float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2; // find the first view that doesn't overlap with the shelf int notGoneIndex = 0; int colorOfViewBeforeLast = NO_COLOR; Loading Loading @@ -233,22 +254,37 @@ public class NotificationShelf extends ActivatableNotificationView implements if (!child.needsClippingToShelf() || child.getVisibility() == GONE) { continue; } float notificationClipEnd; boolean aboveShelf = ViewState.getFinalTranslationZ(child) > baseZHeight || child.isPinned(); boolean isLastChild = child == lastChild; float rowTranslationY = child.getTranslationY(); final float inShelfAmount = updateShelfTransformation(i, child, scrollingFast, expandingAnimated, isLastChild); final float stackEnd = mAmbientState.getStackY() + mAmbientState.getStackHeight(); // TODO(b/172289889) scale mPaddingBetweenElements with expansion amount if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) { notificationClipEnd = shelfStart + getIntrinsicHeight(); notificationClipEnd = stackEnd; } else if (mAmbientState.isExpansionChanging()) { if (mIndexOfFirstViewInOverflowingSection != -1 && i >= mIndexOfFirstViewInOverflowingSection) { // Clip notifications in (section overflowing into shelf) to shelf start. notificationClipEnd = shelfStart - mPaddingBetweenElements; } else { // Clip notifications before the section overflowing into shelf // to stackEnd because we do not show the shelf if the section right before the // shelf is still hidden. notificationClipEnd = stackEnd; } } else { notificationClipEnd = shelfStart - mPaddingBetweenElements; } int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex); clipTopAmount = Math.max(clipTop, clipTopAmount); final float inShelfAmount = updateShelfTransformation(child, scrollingFast, expandingAnimated, isLastChild); // If the current row is an ExpandableNotificationRow, update its color, roundedness, // and icon state. if (child instanceof ExpandableNotificationRow) { Loading Loading @@ -314,19 +350,23 @@ public class NotificationShelf extends ActivatableNotificationView implements distanceToGapTop / mGapHeight); previousAnv.setBottomRoundness(firstElementRoundness, false /* don't animate */); backgroundTop = (int) distanceToGapBottom; } } previousAnv = anv; } } clipTransientViews(); setClipTopAmount(clipTopAmount); boolean isHidden = getViewState().hidden || clipTopAmount >= getIntrinsicHeight(); if (mShowNotificationShelf) { boolean isHidden = getViewState().hidden || clipTopAmount >= getIntrinsicHeight() || !mShowNotificationShelf || numViewsInShelf < 1f; // TODO(b/172289889) transition last icon in shelf to notification icon and vice versa. setVisibility(isHidden ? View.INVISIBLE : View.VISIBLE); } setBackgroundTop(backgroundTop); setFirstElementRoundness(firstElementRoundness); mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex()); Loading @@ -339,11 +379,10 @@ public class NotificationShelf extends ActivatableNotificationView implements continue; } ExpandableNotificationRow row = (ExpandableNotificationRow) child; updateIconClipAmount(row); updateContinuousClipping(row); } boolean hideBackground = numViewsInShelf < 1.0f; setHideBackground(hideBackground || backgroundForceHidden); boolean hideBackground = isHidden; setHideBackground(hideBackground); if (mNotGoneIndex == -1) { mNotGoneIndex = notGoneIndex; } Loading Loading @@ -476,10 +515,10 @@ public class NotificationShelf extends ActivatableNotificationView implements /** * @return the amount how much this notification is in the shelf */ private float updateShelfTransformation(ExpandableView view, boolean scrollingFast, private float updateShelfTransformation(int i, ExpandableView view, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { // Let calculate how much the view is in the shelf // Let's calculate how much the view is in the shelf float viewStart = view.getTranslationY(); int fullHeight = view.getActualHeight() + mPaddingBetweenElements; float iconTransformStart = calculateIconTransformationStart(view); Loading @@ -496,12 +535,18 @@ public class NotificationShelf extends ActivatableNotificationView implements transformDistance, view.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; float fullTransitionAmount = 0.0f; float iconTransitionAmount = 0.0f; float shelfStart = getTranslationY(); if (viewEnd >= shelfStart if (mAmbientState.isExpansionChanging() && !mAmbientState.isOnKeyguard()) { // TODO(b/172289889) handle icon placement for notification that is clipped by the shelf if (mIndexOfFirstViewInShelf != -1 && i >= mIndexOfFirstViewInShelf) { fullTransitionAmount = 1f; iconTransitionAmount = 1f; } } else if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) && (mAmbientState.isShadeExpanded() || (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) { Loading Loading @@ -572,7 +617,7 @@ public class NotificationShelf extends ActivatableNotificationView implements && !mNoAnimationsInThisFrame; } iconState.clampedAppearAmount = clampedAmount; setIconTransformationAmount(view, transitionAmount, isLastChild); setIconTransformationAmount(view, transitionAmount); } private boolean isTargetClipped(ExpandableView view) { Loading @@ -585,12 +630,10 @@ public class NotificationShelf extends ActivatableNotificationView implements + view.getContentTranslation() + view.getRelativeTopPadding(target) + target.getHeight(); return endOfTarget >= getTranslationY() - mPaddingBetweenElements; } private void setIconTransformationAmount(ExpandableView view, float transitionAmount, boolean isLastChild) { private void setIconTransformationAmount(ExpandableView view, float transitionAmount) { if (!(view instanceof ExpandableNotificationRow)) { return; } Loading @@ -601,7 +644,6 @@ public class NotificationShelf extends ActivatableNotificationView implements return; } iconState.alpha = transitionAmount; boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); iconState.hidden = isAppearing || (view instanceof ExpandableNotificationRow Loading @@ -610,8 +652,8 @@ public class NotificationShelf extends ActivatableNotificationView implements || (transitionAmount == 0.0f && !iconState.isAnimating(icon)) || row.isAboveShelf() || row.showingPulsing() || (!row.isInShelf() && isLastChild) || row.getTranslationZ() > mAmbientState.getBaseZHeight(); iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount; // Fade in icons at shelf start Loading Loading @@ -790,8 +832,19 @@ public class NotificationShelf extends ActivatableNotificationView implements mController = notificationShelfController; } public void setIndexOfFirstViewInShelf(ExpandableView firstViewInShelf) { mIndexOfFirstViewInShelf = mHostLayoutController.indexOfChild(firstViewInShelf); } public void setFirstViewInOverflowingSection(ExpandableView firstViewInOverflowingSection) { mIndexOfFirstViewInOverflowingSection = mHostLayoutController.indexOfChild(firstViewInOverflowingSection); } private class ShelfState extends ExpandableViewState { private boolean hasItemsInStableShelf; private ExpandableView firstViewInShelf; private ExpandableView firstViewInOverflowSection; @Override public void applyToView(View view) { Loading @@ -800,6 +853,8 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.applyToView(view); setIndexOfFirstViewInShelf(firstViewInShelf); setFirstViewInOverflowingSection(firstViewInOverflowSection); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading @@ -812,6 +867,8 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.animateTo(child, properties); setIndexOfFirstViewInShelf(firstViewInShelf); setFirstViewInOverflowingSection(firstViewInOverflowSection); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java +4 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope; import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationIconContainer; import com.android.systemui.statusbar.phone.StatusBarNotificationPresenter; Loading Loading @@ -103,9 +104,10 @@ public class NotificationShelfController { return mView.getHeight(); } public void updateState(AmbientState ambientState) { public void updateState(StackScrollAlgorithm.StackScrollAlgorithmState algorithmState, AmbientState ambientState) { mAmbientState = ambientState; mView.updateState(ambientState); mView.updateState(algorithmState, ambientState); } public int getIntrinsicHeight() { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +78 −5 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ public class AmbientState { private NotificationShelf mShelf; private int mZDistanceBetweenElements; private int mBaseZHeight; private int mMaxLayoutHeight; private int mContentHeight; private ExpandableView mLastVisibleBackgroundChild; private float mCurrentScrollVelocity; private int mStatusBarState; Loading @@ -84,6 +84,75 @@ public class AmbientState { private boolean mIsShadeOpening; private float mSectionPadding; /** Distance of top of notifications panel from top of screen. */ private float mStackY = 0; /** Height of notifications panel. */ private float mStackHeight = 0; /** Fraction of shade expansion. */ private float mExpansionFraction; /** Height of the notifications panel without top padding when expansion completes. */ private float mStackEndHeight; /** * @return Height of the notifications panel without top padding when expansion completes. */ public float getStackEndHeight() { return mStackEndHeight; } /** * @param stackEndHeight Height of the notifications panel without top padding * when expansion completes. */ public void setStackEndHeight(float stackEndHeight) { mStackEndHeight = stackEndHeight; } /** * @param stackY Distance of top of notifications panel from top of screen. */ public void setStackY(float stackY) { mStackY = stackY; } /** * @return Distance of top of notifications panel from top of screen. */ public float getStackY() { return mStackY; } /** * @param expansionFraction Fraction of shade expansion. */ public void setExpansionFraction(float expansionFraction) { mExpansionFraction = expansionFraction; } /** * @return Fraction of shade expansion. */ public float getExpansionFraction() { return mExpansionFraction; } /** * @param stackHeight Height of notifications panel. */ public void setStackHeight(float stackHeight) { mStackHeight = stackHeight; } /** * @return Height of notifications panel. */ public float getStackHeight() { return mStackHeight; } /** Tracks the state from AlertingNotificationManager#hasNotifications() */ private boolean mHasAlertEntries; Loading Loading @@ -263,8 +332,8 @@ public class AmbientState { if (mDozeAmount == 1.0f && !isPulseExpanding()) { return mShelf.getHeight(); } int height = Math.max(mLayoutMinHeight, Math.min(mLayoutHeight, mMaxLayoutHeight) - mTopPadding); int height = (int) Math.max(mLayoutMinHeight, Math.min(mLayoutHeight, mContentHeight) - mTopPadding); if (ignorePulseHeight) { return height; } Loading Loading @@ -313,8 +382,12 @@ public class AmbientState { return mShelf; } public void setLayoutMaxHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; public void setContentHeight(int contentHeight) { mContentHeight = contentHeight; } public float getContentHeight() { return mContentHeight; } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +29 −1 Original line number Diff line number Diff line Loading @@ -658,6 +658,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable y = getHeight() - getEmptyBottomMargin(); mDebugPaint.setColor(Color.GREEN); canvas.drawLine(0, y, getWidth(), y, mDebugPaint); y = (int) (mAmbientState.getStackY()); mDebugPaint.setColor(Color.CYAN); canvas.drawLine(0, y, getWidth(), y, mDebugPaint); y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight()); mDebugPaint.setColor(Color.BLUE); canvas.drawLine(0, y, getWidth(), y, mDebugPaint); } } Loading Loading @@ -1123,11 +1131,25 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mTopPaddingNeedsAnimation = true; mNeedsAnimation = true; } updateStackPosition(); requestChildrenUpdate(); notifyHeightChangeListener(null, animate); } } /** * Apply expansion fraction to the y position and height of the notifications panel. */ private void updateStackPosition() { // Consider interpolating from an mExpansionStartY for use on lockscreen and AOD mAmbientState.setStackY( MathUtils.lerp(0, mTopPadding, mAmbientState.getExpansionFraction())); final float shadeBottom = getHeight() - getEmptyBottomMargin(); mAmbientState.setStackEndHeight(shadeBottom - mTopPadding); mAmbientState.setStackHeight( MathUtils.lerp(0, shadeBottom - mTopPadding, mAmbientState.getExpansionFraction())); } /** * Update the height of the panel. * Loading @@ -1135,6 +1157,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ @ShadeViewRefactor(RefactorComponent.COORDINATOR) public void setExpandedHeight(float height) { final float shadeBottom = getHeight() - getEmptyBottomMargin(); final float expansionFraction = MathUtils.constrain(height / shadeBottom, 0f, 1f); mAmbientState.setExpansionFraction(expansionFraction); updateStackPosition(); mExpandedHeight = height; setIsExpanded(height > 0); int minExpansionHeight = getMinExpansionHeight(); Loading Loading @@ -2067,7 +2094,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mContentHeight = height + Math.max(mIntrinsicPadding, mTopPadding) + mBottomMargin; updateScrollability(); clampScrollPosition(); mAmbientState.setLayoutMaxHeight(mContentHeight); updateStackPosition(); mAmbientState.setContentHeight(mContentHeight); } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +4 −0 Original line number Diff line number Diff line Loading @@ -788,6 +788,10 @@ public class NotificationStackScrollLayoutController { return mView.getTranslationX(); } public int indexOfChild(View view) { return mView.indexOfChild(view); } public void setOnHeightChangedListener( ExpandableView.OnHeightChangedListener listener) { mView.setOnHeightChangedListener(listener); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +91 −34 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; import com.android.systemui.statusbar.notification.stack.ViewState; import com.android.systemui.statusbar.phone.NotificationIconContainer; Loading Loading @@ -82,6 +83,9 @@ public class NotificationShelf extends ActivatableNotificationView implements private Rect mClipRect = new Rect(); private int mCutoutHeight; private int mGapHeight; private int mIndexOfFirstViewInShelf = -1; private int mIndexOfFirstViewInOverflowingSection = -1; private NotificationShelfController mController; public NotificationShelf(Context context, AttributeSet attrs) { Loading Loading @@ -159,30 +163,49 @@ public class NotificationShelf extends ActivatableNotificationView implements } /** Update the state of the shelf. */ public void updateState(AmbientState ambientState) { public void updateState(StackScrollAlgorithm.StackScrollAlgorithmState algorithmState, AmbientState ambientState) { ExpandableView lastView = ambientState.getLastVisibleBackgroundChild(); ShelfState viewState = (ShelfState) getViewState(); if (mShowNotificationShelf && lastView != null) { float maxShelfEnd = ambientState.getInnerHeight() + ambientState.getTopPadding() + ambientState.getStackTranslation(); ExpandableViewState lastViewState = lastView.getViewState(); float viewEnd = lastViewState.yTranslation + lastViewState.height; viewState.copyFrom(lastViewState); viewState.height = getIntrinsicHeight(); viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height, getFullyClosedTranslation()); viewState.zTranslation = ambientState.getBaseZHeight(); viewState.clipTopAmount = 0; viewState.alpha = 1f - ambientState.getHideAmount(); viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0; viewState.hideSensitive = false; viewState.xTranslation = getTranslationX(); viewState.hasItemsInStableShelf = lastViewState.inShelf; viewState.firstViewInShelf = algorithmState.firstViewInShelf; viewState.firstViewInOverflowSection = algorithmState.firstViewInOverflowSection; if (mNotGoneIndex != -1) { viewState.notGoneIndex = Math.min(viewState.notGoneIndex, mNotGoneIndex); } viewState.hasItemsInStableShelf = lastViewState.inShelf; viewState.hidden = !mAmbientState.isShadeExpanded() || mAmbientState.isQsCustomizerShowing(); || mAmbientState.isQsCustomizerShowing() || algorithmState.firstViewInShelf == null; final int indexOfFirstViewInShelf = algorithmState.visibleChildren.indexOf( algorithmState.firstViewInShelf); if (mAmbientState.isExpansionChanging() && algorithmState.firstViewInShelf != null && indexOfFirstViewInShelf > 0) { // Show shelf if section before it is showing. final ExpandableView viewBeforeShelf = algorithmState.visibleChildren.get( indexOfFirstViewInShelf - 1); if (viewBeforeShelf.getViewState().hidden) { viewState.hidden = true; } } final float stackEnd = ambientState.getStackY() + ambientState.getStackHeight(); viewState.yTranslation = stackEnd - viewState.height; } else { viewState.hidden = true; viewState.location = ExpandableViewState.LOCATION_GONE; Loading @@ -199,13 +222,11 @@ public class NotificationShelf extends ActivatableNotificationView implements if (!mShowNotificationShelf) { return; } mShelfIcons.resetViewStates(); float shelfStart = getTranslationY(); float numViewsInShelf = 0.0f; View lastChild = mAmbientState.getLastVisibleBackgroundChild(); mNotGoneIndex = -1; float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2; // find the first view that doesn't overlap with the shelf int notGoneIndex = 0; int colorOfViewBeforeLast = NO_COLOR; Loading Loading @@ -233,22 +254,37 @@ public class NotificationShelf extends ActivatableNotificationView implements if (!child.needsClippingToShelf() || child.getVisibility() == GONE) { continue; } float notificationClipEnd; boolean aboveShelf = ViewState.getFinalTranslationZ(child) > baseZHeight || child.isPinned(); boolean isLastChild = child == lastChild; float rowTranslationY = child.getTranslationY(); final float inShelfAmount = updateShelfTransformation(i, child, scrollingFast, expandingAnimated, isLastChild); final float stackEnd = mAmbientState.getStackY() + mAmbientState.getStackHeight(); // TODO(b/172289889) scale mPaddingBetweenElements with expansion amount if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) { notificationClipEnd = shelfStart + getIntrinsicHeight(); notificationClipEnd = stackEnd; } else if (mAmbientState.isExpansionChanging()) { if (mIndexOfFirstViewInOverflowingSection != -1 && i >= mIndexOfFirstViewInOverflowingSection) { // Clip notifications in (section overflowing into shelf) to shelf start. notificationClipEnd = shelfStart - mPaddingBetweenElements; } else { // Clip notifications before the section overflowing into shelf // to stackEnd because we do not show the shelf if the section right before the // shelf is still hidden. notificationClipEnd = stackEnd; } } else { notificationClipEnd = shelfStart - mPaddingBetweenElements; } int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex); clipTopAmount = Math.max(clipTop, clipTopAmount); final float inShelfAmount = updateShelfTransformation(child, scrollingFast, expandingAnimated, isLastChild); // If the current row is an ExpandableNotificationRow, update its color, roundedness, // and icon state. if (child instanceof ExpandableNotificationRow) { Loading Loading @@ -314,19 +350,23 @@ public class NotificationShelf extends ActivatableNotificationView implements distanceToGapTop / mGapHeight); previousAnv.setBottomRoundness(firstElementRoundness, false /* don't animate */); backgroundTop = (int) distanceToGapBottom; } } previousAnv = anv; } } clipTransientViews(); setClipTopAmount(clipTopAmount); boolean isHidden = getViewState().hidden || clipTopAmount >= getIntrinsicHeight(); if (mShowNotificationShelf) { boolean isHidden = getViewState().hidden || clipTopAmount >= getIntrinsicHeight() || !mShowNotificationShelf || numViewsInShelf < 1f; // TODO(b/172289889) transition last icon in shelf to notification icon and vice versa. setVisibility(isHidden ? View.INVISIBLE : View.VISIBLE); } setBackgroundTop(backgroundTop); setFirstElementRoundness(firstElementRoundness); mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex()); Loading @@ -339,11 +379,10 @@ public class NotificationShelf extends ActivatableNotificationView implements continue; } ExpandableNotificationRow row = (ExpandableNotificationRow) child; updateIconClipAmount(row); updateContinuousClipping(row); } boolean hideBackground = numViewsInShelf < 1.0f; setHideBackground(hideBackground || backgroundForceHidden); boolean hideBackground = isHidden; setHideBackground(hideBackground); if (mNotGoneIndex == -1) { mNotGoneIndex = notGoneIndex; } Loading Loading @@ -476,10 +515,10 @@ public class NotificationShelf extends ActivatableNotificationView implements /** * @return the amount how much this notification is in the shelf */ private float updateShelfTransformation(ExpandableView view, boolean scrollingFast, private float updateShelfTransformation(int i, ExpandableView view, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { // Let calculate how much the view is in the shelf // Let's calculate how much the view is in the shelf float viewStart = view.getTranslationY(); int fullHeight = view.getActualHeight() + mPaddingBetweenElements; float iconTransformStart = calculateIconTransformationStart(view); Loading @@ -496,12 +535,18 @@ public class NotificationShelf extends ActivatableNotificationView implements transformDistance, view.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; float fullTransitionAmount = 0.0f; float iconTransitionAmount = 0.0f; float shelfStart = getTranslationY(); if (viewEnd >= shelfStart if (mAmbientState.isExpansionChanging() && !mAmbientState.isOnKeyguard()) { // TODO(b/172289889) handle icon placement for notification that is clipped by the shelf if (mIndexOfFirstViewInShelf != -1 && i >= mIndexOfFirstViewInShelf) { fullTransitionAmount = 1f; iconTransitionAmount = 1f; } } else if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) && (mAmbientState.isShadeExpanded() || (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) { Loading Loading @@ -572,7 +617,7 @@ public class NotificationShelf extends ActivatableNotificationView implements && !mNoAnimationsInThisFrame; } iconState.clampedAppearAmount = clampedAmount; setIconTransformationAmount(view, transitionAmount, isLastChild); setIconTransformationAmount(view, transitionAmount); } private boolean isTargetClipped(ExpandableView view) { Loading @@ -585,12 +630,10 @@ public class NotificationShelf extends ActivatableNotificationView implements + view.getContentTranslation() + view.getRelativeTopPadding(target) + target.getHeight(); return endOfTarget >= getTranslationY() - mPaddingBetweenElements; } private void setIconTransformationAmount(ExpandableView view, float transitionAmount, boolean isLastChild) { private void setIconTransformationAmount(ExpandableView view, float transitionAmount) { if (!(view instanceof ExpandableNotificationRow)) { return; } Loading @@ -601,7 +644,6 @@ public class NotificationShelf extends ActivatableNotificationView implements return; } iconState.alpha = transitionAmount; boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); iconState.hidden = isAppearing || (view instanceof ExpandableNotificationRow Loading @@ -610,8 +652,8 @@ public class NotificationShelf extends ActivatableNotificationView implements || (transitionAmount == 0.0f && !iconState.isAnimating(icon)) || row.isAboveShelf() || row.showingPulsing() || (!row.isInShelf() && isLastChild) || row.getTranslationZ() > mAmbientState.getBaseZHeight(); iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount; // Fade in icons at shelf start Loading Loading @@ -790,8 +832,19 @@ public class NotificationShelf extends ActivatableNotificationView implements mController = notificationShelfController; } public void setIndexOfFirstViewInShelf(ExpandableView firstViewInShelf) { mIndexOfFirstViewInShelf = mHostLayoutController.indexOfChild(firstViewInShelf); } public void setFirstViewInOverflowingSection(ExpandableView firstViewInOverflowingSection) { mIndexOfFirstViewInOverflowingSection = mHostLayoutController.indexOfChild(firstViewInOverflowingSection); } private class ShelfState extends ExpandableViewState { private boolean hasItemsInStableShelf; private ExpandableView firstViewInShelf; private ExpandableView firstViewInOverflowSection; @Override public void applyToView(View view) { Loading @@ -800,6 +853,8 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.applyToView(view); setIndexOfFirstViewInShelf(firstViewInShelf); setFirstViewInOverflowingSection(firstViewInOverflowSection); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading @@ -812,6 +867,8 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.animateTo(child, properties); setIndexOfFirstViewInShelf(firstViewInShelf); setFirstViewInOverflowingSection(firstViewInOverflowSection); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java +4 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope; import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationIconContainer; import com.android.systemui.statusbar.phone.StatusBarNotificationPresenter; Loading Loading @@ -103,9 +104,10 @@ public class NotificationShelfController { return mView.getHeight(); } public void updateState(AmbientState ambientState) { public void updateState(StackScrollAlgorithm.StackScrollAlgorithmState algorithmState, AmbientState ambientState) { mAmbientState = ambientState; mView.updateState(ambientState); mView.updateState(algorithmState, ambientState); } public int getIntrinsicHeight() { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +78 −5 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ public class AmbientState { private NotificationShelf mShelf; private int mZDistanceBetweenElements; private int mBaseZHeight; private int mMaxLayoutHeight; private int mContentHeight; private ExpandableView mLastVisibleBackgroundChild; private float mCurrentScrollVelocity; private int mStatusBarState; Loading @@ -84,6 +84,75 @@ public class AmbientState { private boolean mIsShadeOpening; private float mSectionPadding; /** Distance of top of notifications panel from top of screen. */ private float mStackY = 0; /** Height of notifications panel. */ private float mStackHeight = 0; /** Fraction of shade expansion. */ private float mExpansionFraction; /** Height of the notifications panel without top padding when expansion completes. */ private float mStackEndHeight; /** * @return Height of the notifications panel without top padding when expansion completes. */ public float getStackEndHeight() { return mStackEndHeight; } /** * @param stackEndHeight Height of the notifications panel without top padding * when expansion completes. */ public void setStackEndHeight(float stackEndHeight) { mStackEndHeight = stackEndHeight; } /** * @param stackY Distance of top of notifications panel from top of screen. */ public void setStackY(float stackY) { mStackY = stackY; } /** * @return Distance of top of notifications panel from top of screen. */ public float getStackY() { return mStackY; } /** * @param expansionFraction Fraction of shade expansion. */ public void setExpansionFraction(float expansionFraction) { mExpansionFraction = expansionFraction; } /** * @return Fraction of shade expansion. */ public float getExpansionFraction() { return mExpansionFraction; } /** * @param stackHeight Height of notifications panel. */ public void setStackHeight(float stackHeight) { mStackHeight = stackHeight; } /** * @return Height of notifications panel. */ public float getStackHeight() { return mStackHeight; } /** Tracks the state from AlertingNotificationManager#hasNotifications() */ private boolean mHasAlertEntries; Loading Loading @@ -263,8 +332,8 @@ public class AmbientState { if (mDozeAmount == 1.0f && !isPulseExpanding()) { return mShelf.getHeight(); } int height = Math.max(mLayoutMinHeight, Math.min(mLayoutHeight, mMaxLayoutHeight) - mTopPadding); int height = (int) Math.max(mLayoutMinHeight, Math.min(mLayoutHeight, mContentHeight) - mTopPadding); if (ignorePulseHeight) { return height; } Loading Loading @@ -313,8 +382,12 @@ public class AmbientState { return mShelf; } public void setLayoutMaxHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; public void setContentHeight(int contentHeight) { mContentHeight = contentHeight; } public float getContentHeight() { return mContentHeight; } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +29 −1 Original line number Diff line number Diff line Loading @@ -658,6 +658,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable y = getHeight() - getEmptyBottomMargin(); mDebugPaint.setColor(Color.GREEN); canvas.drawLine(0, y, getWidth(), y, mDebugPaint); y = (int) (mAmbientState.getStackY()); mDebugPaint.setColor(Color.CYAN); canvas.drawLine(0, y, getWidth(), y, mDebugPaint); y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight()); mDebugPaint.setColor(Color.BLUE); canvas.drawLine(0, y, getWidth(), y, mDebugPaint); } } Loading Loading @@ -1123,11 +1131,25 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mTopPaddingNeedsAnimation = true; mNeedsAnimation = true; } updateStackPosition(); requestChildrenUpdate(); notifyHeightChangeListener(null, animate); } } /** * Apply expansion fraction to the y position and height of the notifications panel. */ private void updateStackPosition() { // Consider interpolating from an mExpansionStartY for use on lockscreen and AOD mAmbientState.setStackY( MathUtils.lerp(0, mTopPadding, mAmbientState.getExpansionFraction())); final float shadeBottom = getHeight() - getEmptyBottomMargin(); mAmbientState.setStackEndHeight(shadeBottom - mTopPadding); mAmbientState.setStackHeight( MathUtils.lerp(0, shadeBottom - mTopPadding, mAmbientState.getExpansionFraction())); } /** * Update the height of the panel. * Loading @@ -1135,6 +1157,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ @ShadeViewRefactor(RefactorComponent.COORDINATOR) public void setExpandedHeight(float height) { final float shadeBottom = getHeight() - getEmptyBottomMargin(); final float expansionFraction = MathUtils.constrain(height / shadeBottom, 0f, 1f); mAmbientState.setExpansionFraction(expansionFraction); updateStackPosition(); mExpandedHeight = height; setIsExpanded(height > 0); int minExpansionHeight = getMinExpansionHeight(); Loading Loading @@ -2067,7 +2094,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mContentHeight = height + Math.max(mIntrinsicPadding, mTopPadding) + mBottomMargin; updateScrollability(); clampScrollPosition(); mAmbientState.setLayoutMaxHeight(mContentHeight); updateStackPosition(); mAmbientState.setContentHeight(mContentHeight); } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +4 −0 Original line number Diff line number Diff line Loading @@ -788,6 +788,10 @@ public class NotificationStackScrollLayoutController { return mView.getTranslationX(); } public int indexOfChild(View view) { return mView.indexOfChild(view); } public void setOnHeightChangedListener( ExpandableView.OnHeightChangedListener listener) { mView.setOnHeightChangedListener(listener); Loading