diff options
| author | 2022-08-30 20:59:46 +0000 | |
|---|---|---|
| committer | 2022-08-30 20:59:46 +0000 | |
| commit | 55de757247c8bd8fc49a0e971b88e5b1b7f252d5 (patch) | |
| tree | 9022a92f683f13af788ac4faec9d7975850a2f8f | |
| parent | fc02b01feb5a3c50a08ec70b0f684fc7740b666f (diff) | |
| parent | d9b74e5bfe46020cafa376bf78f8b52013d6cc1c (diff) | |
Merge "Fix "No Notification" text not gradually showing on LockScreen" into tm-qpr-dev am: 0162aec6c8 am: d9b74e5bfe
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19606335
Change-Id: I8f39628c2d3cf957c714569bac8441aaf47baec8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
9 files changed, 251 insertions, 64 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java index b9684fcb8a01..3d161d9bfa75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java @@ -24,6 +24,8 @@ import android.util.AttributeSet; import android.view.View; import android.widget.TextView; +import androidx.annotation.NonNull; + import com.android.systemui.R; import com.android.systemui.statusbar.notification.row.StackScrollerDecorView; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; @@ -73,6 +75,7 @@ public class EmptyShadeView extends StackScrollerDecorView { } @Override + @NonNull public ExpandableViewState createExpandableViewState() { return new EmptyShadeViewState(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 221428747558..cea3debe6379 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -29,6 +29,8 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import androidx.annotation.NonNull; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.R; @@ -153,6 +155,7 @@ public class NotificationShelf extends ActivatableNotificationView implements } @Override + @NonNull public ExpandableViewState createExpandableViewState() { return new ShelfState(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 855390d75ff8..8574f872ad9c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -25,8 +25,6 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationChannel; @@ -68,6 +66,9 @@ import android.widget.Chronometer; import android.widget.FrameLayout; import android.widget.ImageView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -3247,6 +3248,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } @Override + @NonNull public ExpandableViewState createExpandableViewState() { return new NotificationViewState(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java index 8f73b802271d..1e09b8a37645 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java @@ -29,6 +29,7 @@ import android.view.ViewGroup; import android.view.ViewParent; import android.widget.FrameLayout; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.systemui.Dumpable; @@ -66,7 +67,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable { protected float mContentTransformationAmount; protected boolean mIsLastChild; protected int mContentShift; - private final ExpandableViewState mViewState; + @NonNull private final ExpandableViewState mViewState; private float mContentTranslation; protected boolean mLastInSection; protected boolean mFirstInSection; @@ -610,6 +611,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable { public void setActualHeightAnimating(boolean animating) {} + @NonNull protected ExpandableViewState createExpandableViewState() { return new ExpandableViewState(); } @@ -642,7 +644,12 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable { return mViewState; } - @Nullable public ExpandableViewState getViewState() { + /** + * Get the {@link ExpandableViewState} associated with the view. + * + * @return the ExpandableView's view state. + */ + @NonNull public ExpandableViewState getViewState() { return mViewState; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java index e43ecf70a308..49dc6550a51f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java @@ -23,6 +23,8 @@ import android.util.AttributeSet; import android.util.IndentingPrintWriter; import android.view.View; +import androidx.annotation.NonNull; + import com.android.systemui.R; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; import com.android.systemui.statusbar.notification.stack.ViewState; @@ -142,6 +144,7 @@ public class FooterView extends StackScrollerDecorView { } @Override + @NonNull public ExpandableViewState createExpandableViewState() { return new FooterViewState(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index cc87499d39cb..1fb265fea0b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -4460,8 +4460,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } private void updateVisibility() { - boolean shouldShow = !mAmbientState.isFullyHidden() || !onKeyguard(); - setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE); + mController.updateVisibility(!mAmbientState.isFullyHidden() || !onKeyguard()); } @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @@ -4526,17 +4525,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - void updateEmptyShadeView(boolean visible, boolean notifVisibleInShade) { + void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) { mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled); int oldTextRes = mEmptyShadeView.getTextResource(); - int newTextRes = notifVisibleInShade + int newTextRes = areNotificationsHiddenInShade ? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text; if (oldTextRes != newTextRes) { mEmptyShadeView.setText(newTextRes); } } + public boolean isEmptyShadeViewVisible() { + return mEmptyShadeView.isVisible(); + } + @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) { if (mFooterView == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index e6eceb555897..ec1e6207ef8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -177,7 +177,6 @@ public class NotificationStackScrollLayoutController { private NotificationStackScrollLayout mView; private boolean mFadeNotificationsOnDismiss; private NotificationSwipeHelper mSwipeHelper; - private boolean mShowEmptyShadeView; @Nullable private Boolean mHistoryEnabled; private int mBarState; private HeadsUpAppearanceController mHeadsUpAppearanceController; @@ -1173,8 +1172,21 @@ public class NotificationStackScrollLayoutController { } /** - * Update whether we should show the empty shade view (no notifications in the shade). - * If so, send the update to our view. + * Set the visibility of the view, and propagate it to specific children. + * + * @param visible either the view is visible or not. + */ + public void updateVisibility(boolean visible) { + mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); + + if (mView.getVisibility() == View.VISIBLE) { + // Synchronize EmptyShadeView visibility with the parent container. + updateShowEmptyShadeView(); + } + } + + /** + * Update whether we should show the empty shade view ("no notifications" in the shade). * * When in split mode, notifications are always visible regardless of the state of the * QuickSettings panel. That being the case, empty view is always shown if the other conditions @@ -1182,18 +1194,31 @@ public class NotificationStackScrollLayoutController { */ public void updateShowEmptyShadeView() { Trace.beginSection("NSSLC.updateShowEmptyShadeView"); - mShowEmptyShadeView = mStatusBarStateController.getCurrentOrUpcomingState() != KEYGUARD + + final boolean shouldShow = getVisibleNotificationCount() == 0 && !mView.isQsFullScreen() - && getVisibleNotificationCount() == 0; + // Hide empty shade view when in transition to Keyguard. + // That avoids "No Notifications" to blink when transitioning to AOD. + // For more details, see: b/228790482 + && !isInTransitionToKeyguard(); + + mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade()); - mView.updateEmptyShadeView( - mShowEmptyShadeView, - mZenModeController.areNotificationsHiddenInShade()); Trace.endSection(); } + /** + * @return true if {@link StatusBarStateController} is in transition to the KEYGUARD + * and false otherwise. + */ + private boolean isInTransitionToKeyguard() { + final int currentState = mStatusBarStateController.getState(); + final int upcomingState = mStatusBarStateController.getCurrentOrUpcomingState(); + return (currentState != upcomingState && upcomingState == KEYGUARD); + } + public boolean isShowingEmptyShadeView() { - return mShowEmptyShadeView; + return mView.isEmptyShadeViewVisible(); } public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 6d513d0da5c1..353355bef7bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -120,11 +120,64 @@ public class StackScrollAlgorithm { updateClipping(algorithmState, ambientState); updateSpeedBumpState(algorithmState, speedBumpIndex); updateShelfState(algorithmState, ambientState); + updateAlphaState(algorithmState, ambientState); getNotificationChildrenStates(algorithmState, ambientState); } + private void updateAlphaState(StackScrollAlgorithmState algorithmState, + AmbientState ambientState) { + for (ExpandableView view : algorithmState.visibleChildren) { + final ViewState viewState = view.getViewState(); + + final boolean isHunGoingToShade = ambientState.isShadeExpanded() + && view == ambientState.getTrackedHeadsUpRow(); + + if (isHunGoingToShade) { + // Keep 100% opacity for heads up notification going to shade. + viewState.alpha = 1f; + } else if (ambientState.isOnKeyguard()) { + // Adjust alpha for wakeup to lockscreen. + viewState.alpha = 1f - ambientState.getHideAmount(); + } else if (ambientState.isExpansionChanging()) { + // Adjust alpha for shade open & close. + float expansion = ambientState.getExpansionFraction(); + viewState.alpha = ambientState.isBouncerInTransit() + ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion) + : ShadeInterpolation.getContentAlpha(expansion); + } + + // For EmptyShadeView if on keyguard, we need to control the alpha to create + // a nice transition when the user is dragging down the notification panel. + if (view instanceof EmptyShadeView && ambientState.isOnKeyguard()) { + final float fractionToShade = ambientState.getFractionToShade(); + viewState.alpha = ShadeInterpolation.getContentAlpha(fractionToShade); + } + + NotificationShelf shelf = ambientState.getShelf(); + if (shelf != null) { + final ViewState shelfState = shelf.getViewState(); + + // After the shelf has updated its yTranslation, explicitly set alpha=0 for view + // below shelf to skip rendering them in the hardware layer. We do not set them + // invisible because that runs invalidate & onDraw when these views return onscreen, + // which is more expensive. + if (shelfState.hidden) { + // When the shelf is hidden, it won't clip views, so we don't hide rows + return; + } + + final float shelfTop = shelfState.yTranslation; + final float viewTop = viewState.yTranslation; + if (viewTop >= shelfTop) { + viewState.alpha = 0; + } + } + } + } + /** * How expanded or collapsed notifications are when pulling down the shade. + * * @param ambientState Current ambient state. * @return 0 when fully collapsed, 1 when expanded. */ @@ -208,22 +261,6 @@ public class StackScrollAlgorithm { } shelf.updateState(algorithmState, ambientState); - - // After the shelf has updated its yTranslation, explicitly set alpha=0 for view below shelf - // to skip rendering them in the hardware layer. We do not set them invisible because that - // runs invalidate & onDraw when these views return onscreen, which is more expensive. - if (shelf.getViewState().hidden) { - // When the shelf is hidden, it won't clip views, so we don't hide rows - return; - } - final float shelfTop = shelf.getViewState().yTranslation; - - for (ExpandableView view : algorithmState.visibleChildren) { - final float viewTop = view.getViewState().yTranslation; - if (viewTop >= shelfTop) { - view.getViewState().alpha = 0; - } - } } private void updateClipping(StackScrollAlgorithmState algorithmState, @@ -473,21 +510,6 @@ public class StackScrollAlgorithm { ExpandableViewState viewState = view.getViewState(); viewState.location = ExpandableViewState.LOCATION_UNKNOWN; - final boolean isHunGoingToShade = ambientState.isShadeExpanded() - && view == ambientState.getTrackedHeadsUpRow(); - if (isHunGoingToShade) { - // Keep 100% opacity for heads up notification going to shade. - } else if (ambientState.isOnKeyguard()) { - // Adjust alpha for wakeup to lockscreen. - viewState.alpha = 1f - ambientState.getHideAmount(); - } else if (ambientState.isExpansionChanging()) { - // Adjust alpha for shade open & close. - float expansion = ambientState.getExpansionFraction(); - viewState.alpha = ambientState.isBouncerInTransit() - ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion) - : ShadeInterpolation.getContentAlpha(expansion); - } - final float expansionFraction = getExpansionFractionWithoutShelf( algorithmState, ambientState); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index 8fd6842911de..35d2363b1c2a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -3,19 +3,21 @@ package com.android.systemui.statusbar.notification.stack import android.annotation.DimenRes import android.widget.FrameLayout import androidx.test.filters.SmallTest +import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.ShadeInterpolation.getContentAlpha import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.EmptyShadeView +import com.android.systemui.statusbar.NotificationShelf +import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView -import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController -import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.google.common.truth.Truth.assertThat +import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue -import junit.framework.Assert.assertEquals import org.junit.Before import org.junit.Test import org.mockito.Mockito.mock @@ -26,17 +28,20 @@ class StackScrollAlgorithmTest : SysuiTestCase() { private val hostView = FrameLayout(context) private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView) - private val expandableViewState = ExpandableViewState() private val notificationRow = mock(ExpandableNotificationRow::class.java) private val dumpManager = mock(DumpManager::class.java) private val mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager::class.java) + private val notificationShelf = mock(NotificationShelf::class.java) + private val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply { + layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100) + } private val ambientState = AmbientState( - context, - dumpManager, - SectionProvider { _, _ -> false }, - BypassController { false }, - mStatusBarKeyguardViewManager + context, + dumpManager, + /* sectionProvider */ { _, _ -> false }, + /* bypassController */ { false }, + mStatusBarKeyguardViewManager ) private val testableResources = mContext.orCreateTestableResources @@ -49,7 +54,9 @@ class StackScrollAlgorithmTest : SysuiTestCase() { @Before fun setUp() { - whenever(notificationRow.viewState).thenReturn(expandableViewState) + whenever(notificationShelf.viewState).thenReturn(ExpandableViewState()) + whenever(notificationRow.viewState).thenReturn(ExpandableViewState()) + hostView.addView(notificationRow) } @@ -60,7 +67,8 @@ class StackScrollAlgorithmTest : SysuiTestCase() { stackScrollAlgorithm.resetViewStates(ambientState, 0) - assertThat(expandableViewState.yTranslation).isEqualTo(stackScrollAlgorithm.mHeadsUpInset) + assertThat(notificationRow.viewState.yTranslation) + .isEqualTo(stackScrollAlgorithm.mHeadsUpInset) } @Test @@ -75,15 +83,12 @@ class StackScrollAlgorithmTest : SysuiTestCase() { stackScrollAlgorithm.resetViewStates(ambientState, 0) // top margin presence should decrease heads up translation up to minHeadsUpTranslation - assertThat(expandableViewState.yTranslation).isEqualTo(minHeadsUpTranslation) + assertThat(notificationRow.viewState.yTranslation).isEqualTo(minHeadsUpTranslation) } @Test fun resetViewStates_emptyShadeView_isCenteredVertically() { stackScrollAlgorithm.initView(context) - val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply { - layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100) - } hostView.removeAllViews() hostView.addView(emptyShadeView) ambientState.layoutMaxHeight = 1280 @@ -98,6 +103,121 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } @Test + fun resetViewStates_hunGoingToShade_viewBecomesOpaque() { + whenever(notificationRow.isAboveShelf).thenReturn(true) + ambientState.isShadeExpanded = true + ambientState.trackedHeadsUpRow = notificationRow + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + assertThat(notificationRow.viewState.alpha).isEqualTo(1f) + } + + @Test + fun resetViewStates_isExpansionChanging_viewBecomesTransparent() { + whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(false) + ambientState.isExpansionChanging = true + ambientState.expansionFraction = 0.25f + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + val expected = getContentAlpha(0.25f) + assertThat(notificationRow.viewState.alpha).isEqualTo(expected) + } + + @Test + fun resetViewStates_isExpansionChangingWhileBouncerInTransit_viewBecomesTransparent() { + whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(true) + ambientState.isExpansionChanging = true + ambientState.expansionFraction = 0.25f + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + val expected = aboutToShowBouncerProgress(0.25f) + assertThat(notificationRow.viewState.alpha).isEqualTo(expected) + } + + @Test + fun resetViewStates_isOnKeyguard_viewBecomesTransparent() { + ambientState.setStatusBarState(StatusBarState.KEYGUARD) + ambientState.hideAmount = 0.25f + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + assertThat(notificationRow.viewState.alpha).isEqualTo(1f - ambientState.hideAmount) + } + + @Test + fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesTransparent() { + ambientState.setStatusBarState(StatusBarState.KEYGUARD) + ambientState.fractionToShade = 0.25f + stackScrollAlgorithm.initView(context) + hostView.removeAllViews() + hostView.addView(emptyShadeView) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + val expected = getContentAlpha(ambientState.fractionToShade) + assertThat(emptyShadeView.viewState.alpha).isEqualTo(expected) + } + + @Test + fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesOpaque() { + ambientState.setStatusBarState(StatusBarState.SHADE) + ambientState.fractionToShade = 0.25f + stackScrollAlgorithm.initView(context) + hostView.removeAllViews() + hostView.addView(emptyShadeView) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + assertThat(emptyShadeView.viewState.alpha).isEqualTo(1f) + } + + @Test + fun resetViewStates_hiddenShelf_viewAlphaDoesNotChange() { + val expected = notificationShelf.viewState.alpha + notificationShelf.viewState.hidden = true + ambientState.shelf = notificationShelf + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + assertThat(notificationShelf.viewState.alpha).isEqualTo(expected) + } + + @Test + fun resetViewStates_shelfTopLessThanViewTop_hidesView() { + notificationRow.viewState.yTranslation = 10f + notificationShelf.viewState.yTranslation = 0.9f + notificationShelf.viewState.hidden = false + ambientState.shelf = notificationShelf + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + assertThat(notificationRow.viewState.alpha).isEqualTo(0f) + } + + @Test + fun resetViewStates_shelfTopGreaterOrEqualThanViewTop_viewAlphaDoesNotChange() { + val expected = notificationRow.viewState.alpha + notificationRow.viewState.yTranslation = 10f + notificationShelf.viewState.yTranslation = 10f + notificationShelf.viewState.hidden = false + ambientState.shelf = notificationShelf + stackScrollAlgorithm.initView(context) + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + assertThat(notificationRow.viewState.alpha).isEqualTo(expected) + } + + @Test fun getGapForLocation_onLockscreen_returnsSmallGap() { val gap = stackScrollAlgorithm.getGapForLocation( /* fractionToShade= */ 0f, /* onKeyguard= */ true) @@ -267,7 +387,6 @@ class StackScrollAlgorithmTest : SysuiTestCase() { assertEquals(10f, expandableViewState.yTranslation) } - @Test fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() { val expandableViewState = ExpandableViewState() |