Merge "Fix missing HUN Outro animations" into udc-dev am: 2803d28eb1
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23601638 Change-Id: I0a2c893fcc947bb082054c2917471a51449984c6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -315,7 +315,8 @@ public class StackScrollAlgorithm {
|
|||||||
float newNotificationEnd = newYTranslation + newHeight;
|
float newNotificationEnd = newYTranslation + newHeight;
|
||||||
boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
|
boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
|
||||||
if (mClipNotificationScrollToTop
|
if (mClipNotificationScrollToTop
|
||||||
&& ((isHeadsUp && !firstHeadsUp) || child.isHeadsUpAnimatingAway())
|
&& !firstHeadsUp
|
||||||
|
&& (isHeadsUp || child.isHeadsUpAnimatingAway())
|
||||||
&& newNotificationEnd > firstHeadsUpEnd
|
&& newNotificationEnd > firstHeadsUpEnd
|
||||||
&& !ambientState.isShadeExpanded()) {
|
&& !ambientState.isShadeExpanded()) {
|
||||||
// The bottom of this view is peeking out from under the previous view.
|
// The bottom of this view is peeking out from under the previous view.
|
||||||
@@ -619,13 +620,12 @@ public class StackScrollAlgorithm {
|
|||||||
updateViewWithShelf(view, viewState, shelfStart);
|
updateViewWithShelf(view, viewState, shelfStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Avoid pulsing notification flicker during AOD to LS
|
viewState.height = getMaxAllowedChildHeight(view);
|
||||||
// A pulsing notification is already expanded, no need to expand it again with animation
|
if (!view.isPinned() && !view.isHeadsUpAnimatingAway()
|
||||||
if (ambientState.isPulsingRow(view)) {
|
&& !ambientState.isPulsingRow(view)) {
|
||||||
expansionFraction = 1.0f;
|
// 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 +=
|
algorithmState.mCurrentYPosition +=
|
||||||
@@ -785,6 +785,8 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (row.isPinned()) {
|
if (row.isPinned()) {
|
||||||
|
// Make sure row yTranslation is at maximum the HUN yTranslation,
|
||||||
|
// which accounts for AmbientState.stackTopMargin in split-shade.
|
||||||
childState.setYTranslation(
|
childState.setYTranslation(
|
||||||
Math.max(childState.getYTranslation(), headsUpTranslation));
|
Math.max(childState.getYTranslation(), headsUpTranslation));
|
||||||
childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
|
childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
|
||||||
@@ -809,7 +811,11 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (row.isHeadsUpAnimatingAway()) {
|
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;
|
childState.hidden = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import org.mockito.Mockito.`when` as whenever
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
class StackScrollAlgorithmTest : SysuiTestCase() {
|
class StackScrollAlgorithmTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
|
||||||
@JvmField @Rule
|
@JvmField @Rule
|
||||||
var expect: Expect = Expect.create()
|
var expect: Expect = Expect.create()
|
||||||
|
|
||||||
@@ -82,26 +81,58 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
fun resetViewStates_defaultHun_yTranslationIsInset() {
|
fun resetViewStates_defaultHun_yTranslationIsInset() {
|
||||||
whenever(notificationRow.isPinned).thenReturn(true)
|
whenever(notificationRow.isPinned).thenReturn(true)
|
||||||
whenever(notificationRow.isHeadsUp).thenReturn(true)
|
whenever(notificationRow.isHeadsUp).thenReturn(true)
|
||||||
|
resetViewStates_hunYTranslationIsInset()
|
||||||
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
|
||||||
|
|
||||||
assertThat(notificationRow.viewState.yTranslation)
|
|
||||||
.isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun resetViewStates_stackMargin_changesHunYTranslation() {
|
fun resetViewStates_defaultHunWithStackMargin_changesHunYTranslation() {
|
||||||
whenever(notificationRow.isPinned).thenReturn(true)
|
whenever(notificationRow.isPinned).thenReturn(true)
|
||||||
whenever(notificationRow.isHeadsUp).thenReturn(true)
|
whenever(notificationRow.isHeadsUp).thenReturn(true)
|
||||||
val minHeadsUpTranslation = context.resources
|
resetViewStates_stackMargin_changesHunYTranslation()
|
||||||
.getDimensionPixelSize(R.dimen.notification_side_paddings)
|
}
|
||||||
|
|
||||||
// split shade case with top margin introduced by shade's status bar
|
@Test
|
||||||
ambientState.stackTopMargin = 100
|
fun resetViewStates_hunAnimatingAway_yTranslationIsInset() {
|
||||||
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
|
||||||
|
resetViewStates_hunYTranslationIsInset()
|
||||||
|
}
|
||||||
|
|
||||||
// top margin presence should decrease heads up translation up to minHeadsUpTranslation
|
@Test
|
||||||
assertThat(notificationRow.viewState.yTranslation).isEqualTo(minHeadsUpTranslation)
|
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
|
@Test
|
||||||
@@ -855,6 +886,57 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
ambientState.stackHeight = ambientState.stackEndHeight * fraction
|
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(
|
private fun resetViewStates_expansionChanging_notificationAlphaUpdated(
|
||||||
expansionFraction: Float,
|
expansionFraction: Float,
|
||||||
expectedAlpha: Float,
|
expectedAlpha: Float,
|
||||||
|
|||||||
Reference in New Issue
Block a user