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