Merge "Fix missing HUN Outro animations" into udc-dev

This commit is contained in:
András Kurucz
2023-06-12 15:38:44 +00:00
committed by Android (Google) Code Review
2 changed files with 110 additions and 22 deletions

View File

@@ -315,7 +315,8 @@ public class StackScrollAlgorithm {
float newNotificationEnd = newYTranslation + newHeight;
boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
if (mClipNotificationScrollToTop
&& ((isHeadsUp && !firstHeadsUp) || child.isHeadsUpAnimatingAway())
&& !firstHeadsUp
&& (isHeadsUp || child.isHeadsUpAnimatingAway())
&& newNotificationEnd > firstHeadsUpEnd
&& !ambientState.isShadeExpanded()) {
// The bottom of this view is peeking out from under the previous view.
@@ -619,13 +620,12 @@ public class StackScrollAlgorithm {
updateViewWithShelf(view, viewState, shelfStart);
}
}
// Avoid pulsing notification flicker during AOD to LS
// A pulsing notification is already expanded, no need to expand it again with animation
if (ambientState.isPulsingRow(view)) {
expansionFraction = 1.0f;
viewState.height = getMaxAllowedChildHeight(view);
if (!view.isPinned() && !view.isHeadsUpAnimatingAway()
&& !ambientState.isPulsingRow(view)) {
// The expansion fraction should not affect HUNs or pulsing notifications.
viewState.height *= expansionFraction;
}
// Clip height of view right before shelf.
viewState.height = (int) (getMaxAllowedChildHeight(view) * expansionFraction);
}
algorithmState.mCurrentYPosition +=
@@ -785,6 +785,8 @@ public class StackScrollAlgorithm {
}
}
if (row.isPinned()) {
// Make sure row yTranslation is at maximum the HUN yTranslation,
// which accounts for AmbientState.stackTopMargin in split-shade.
childState.setYTranslation(
Math.max(childState.getYTranslation(), headsUpTranslation));
childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
@@ -809,7 +811,11 @@ public class StackScrollAlgorithm {
}
}
if (row.isHeadsUpAnimatingAway()) {
childState.setYTranslation(Math.max(childState.getYTranslation(), mHeadsUpInset));
// Make sure row yTranslation is at maximum the HUN yTranslation,
// which accounts for AmbientState.stackTopMargin in split-shade.
childState.setYTranslation(
Math.max(childState.getYTranslation(), headsUpTranslation));
// keep it visible for the animation
childState.hidden = false;
}
}

View File

@@ -35,7 +35,6 @@ import org.mockito.Mockito.`when` as whenever
@SmallTest
class StackScrollAlgorithmTest : SysuiTestCase() {
@JvmField @Rule
var expect: Expect = Expect.create()
@@ -82,26 +81,58 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
fun resetViewStates_defaultHun_yTranslationIsInset() {
whenever(notificationRow.isPinned).thenReturn(true)
whenever(notificationRow.isHeadsUp).thenReturn(true)
stackScrollAlgorithm.resetViewStates(ambientState, 0)
assertThat(notificationRow.viewState.yTranslation)
.isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
resetViewStates_hunYTranslationIsInset()
}
@Test
fun resetViewStates_stackMargin_changesHunYTranslation() {
fun resetViewStates_defaultHunWithStackMargin_changesHunYTranslation() {
whenever(notificationRow.isPinned).thenReturn(true)
whenever(notificationRow.isHeadsUp).thenReturn(true)
val minHeadsUpTranslation = context.resources
.getDimensionPixelSize(R.dimen.notification_side_paddings)
resetViewStates_stackMargin_changesHunYTranslation()
}
// split shade case with top margin introduced by shade's status bar
ambientState.stackTopMargin = 100
stackScrollAlgorithm.resetViewStates(ambientState, 0)
@Test
fun resetViewStates_hunAnimatingAway_yTranslationIsInset() {
whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
resetViewStates_hunYTranslationIsInset()
}
// top margin presence should decrease heads up translation up to minHeadsUpTranslation
assertThat(notificationRow.viewState.yTranslation).isEqualTo(minHeadsUpTranslation)
@Test
fun resetViewStates_hunAnimatingAway_StackMarginChangesHunYTranslation() {
whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
resetViewStates_stackMargin_changesHunYTranslation()
}
@Test
fun resetViewStates_hunAnimatingAway_bottomNotClipped() {
whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
assertThat(notificationRow.viewState.clipBottomAmount).isEqualTo(0)
}
@Test
fun resetViewStates_hunsOverlapping_bottomHunClipped() {
val topHun = mockExpandableNotificationRow()
val bottomHun = mockExpandableNotificationRow()
whenever(topHun.isHeadsUp).thenReturn(true)
whenever(topHun.isPinned).thenReturn(true)
whenever(bottomHun.isHeadsUp).thenReturn(true)
whenever(bottomHun.isPinned).thenReturn(true)
resetViewStates_hunsOverlapping_bottomHunClipped(topHun, bottomHun)
}
@Test
fun resetViewStates_hunsOverlappingAndBottomHunAnimatingAway_bottomHunClipped() {
val topHun = mockExpandableNotificationRow()
val bottomHun = mockExpandableNotificationRow()
whenever(topHun.isHeadsUp).thenReturn(true)
whenever(topHun.isPinned).thenReturn(true)
whenever(bottomHun.isHeadsUpAnimatingAway).thenReturn(true)
resetViewStates_hunsOverlapping_bottomHunClipped(topHun, bottomHun)
}
@Test
@@ -855,6 +886,57 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
ambientState.stackHeight = ambientState.stackEndHeight * fraction
}
private fun resetViewStates_hunYTranslationIsInset() {
stackScrollAlgorithm.resetViewStates(ambientState, 0)
assertThat(notificationRow.viewState.yTranslation)
.isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
}
private fun resetViewStates_stackMargin_changesHunYTranslation() {
val stackTopMargin = 50
val headsUpTranslationY = stackScrollAlgorithm.mHeadsUpInset - stackTopMargin
// we need the shelf to mock the real-life behaviour of StackScrollAlgorithm#updateChild
ambientState.shelf = notificationShelf
// split shade case with top margin introduced by shade's status bar
ambientState.stackTopMargin = stackTopMargin
stackScrollAlgorithm.resetViewStates(ambientState, 0)
// heads up translation should be decreased by the top margin
assertThat(notificationRow.viewState.yTranslation).isEqualTo(headsUpTranslationY)
}
private fun resetViewStates_hunsOverlapping_bottomHunClipped(
topHun: ExpandableNotificationRow,
bottomHun: ExpandableNotificationRow
) {
val topHunHeight = mContext.resources.getDimensionPixelSize(
R.dimen.notification_content_min_height)
val bottomHunHeight = mContext.resources.getDimensionPixelSize(
R.dimen.notification_max_heads_up_height)
whenever(topHun.intrinsicHeight).thenReturn(topHunHeight)
whenever(bottomHun.intrinsicHeight).thenReturn(bottomHunHeight)
// we need the shelf to mock the real-life behaviour of StackScrollAlgorithm#updateChild
ambientState.shelf = notificationShelf
// add two overlapping HUNs
hostView.removeAllViews()
hostView.addView(topHun)
hostView.addView(bottomHun)
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
// the height shouldn't change
assertThat(topHun.viewState.height).isEqualTo(topHunHeight)
assertThat(bottomHun.viewState.height).isEqualTo(bottomHunHeight)
// the HUN at the bottom should be clipped
assertThat(topHun.viewState.clipBottomAmount).isEqualTo(0)
assertThat(bottomHun.viewState.clipBottomAmount).isEqualTo(bottomHunHeight - topHunHeight)
}
private fun resetViewStates_expansionChanging_notificationAlphaUpdated(
expansionFraction: Float,
expectedAlpha: Float,