1 package com.android.systemui.statusbar.notification.stack 2 3 import android.widget.FrameLayout 4 import androidx.test.filters.SmallTest 5 import com.android.systemui.R 6 import com.android.systemui.SysuiTestCase 7 import com.android.systemui.statusbar.EmptyShadeView 8 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow 9 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController 10 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider 11 import com.google.common.truth.Truth.assertThat 12 import org.junit.Before 13 import org.junit.Test 14 import org.mockito.Mockito.mock 15 import org.mockito.Mockito.`when` as whenever 16 17 @SmallTest 18 class StackScrollAlgorithmTest : SysuiTestCase() { 19 20 private val hostView = FrameLayout(context) 21 private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView) 22 private val expandableViewState = ExpandableViewState() 23 private val notificationRow = mock(ExpandableNotificationRow::class.java) 24 private val ambientState = AmbientState( 25 context, 26 SectionProvider { _, _ -> false }, 27 BypassController { false }) 28 29 @Before 30 fun setUp() { 31 whenever(notificationRow.viewState).thenReturn(expandableViewState) 32 hostView.addView(notificationRow) 33 } 34 35 @Test 36 fun testUpTranslationSetToDefaultValue() { 37 whenever(notificationRow.isPinned).thenReturn(true) 38 whenever(notificationRow.isHeadsUp).thenReturn(true) 39 40 stackScrollAlgorithm.resetViewStates(ambientState, 0) 41 42 assertThat(expandableViewState.yTranslation).isEqualTo(stackScrollAlgorithm.mHeadsUpInset) 43 } 44 45 @Test 46 fun testHeadsUpTranslationChangesBasedOnStackMargin() { 47 whenever(notificationRow.isPinned).thenReturn(true) 48 whenever(notificationRow.isHeadsUp).thenReturn(true) 49 val minHeadsUpTranslation = context.resources 50 .getDimensionPixelSize(R.dimen.notification_side_paddings) 51 52 // split shade case with top margin introduced by shade's status bar 53 ambientState.stackTopMargin = 100 54 stackScrollAlgorithm.resetViewStates(ambientState, 0) 55 56 // top margin presence should decrease heads up translation up to minHeadsUpTranslation 57 assertThat(expandableViewState.yTranslation).isEqualTo(minHeadsUpTranslation) 58 } 59 60 @Test 61 fun resetViewStates_childIsEmptyShadeView_viewIsCenteredVertically() { 62 stackScrollAlgorithm.initView(context) 63 val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply { 64 layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100) 65 } 66 hostView.removeAllViews() 67 hostView.addView(emptyShadeView) 68 ambientState.layoutMaxHeight = 1280 69 70 stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) 71 72 val closeHandleUnderlapHeight = 73 context.resources.getDimensionPixelSize(R.dimen.close_handle_underlap) 74 val fullHeight = 75 ambientState.layoutMaxHeight + closeHandleUnderlapHeight - ambientState.stackY 76 val centeredY = ambientState.stackY + fullHeight / 2f - emptyShadeView.height / 2f 77 assertThat(emptyShadeView.viewState?.yTranslation).isEqualTo(centeredY) 78 } 79 } 80