1 package com.android.systemui.statusbar.notification
2 
3 import android.view.View
4 import androidx.test.ext.junit.runners.AndroidJUnit4
5 import androidx.test.filters.SmallTest
6 import com.android.systemui.SysuiTestCase
7 import com.android.systemui.util.mockito.mock
8 import com.android.systemui.util.mockito.whenever
9 import org.junit.Assert.assertEquals
10 import org.junit.Test
11 import org.junit.runner.RunWith
12 import org.mockito.Mockito.atLeastOnce
13 import org.mockito.Mockito.times
14 import org.mockito.Mockito.verify
15 
16 @SmallTest
17 @RunWith(AndroidJUnit4::class)
18 class RoundableTest : SysuiTestCase() {
19     private val targetView: View = mock()
20     private val roundable = FakeRoundable(targetView = targetView)
21 
22     @Test
defaultConfig_shouldNotHaveRoundedCornernull23     fun defaultConfig_shouldNotHaveRoundedCorner() {
24         // the expected default value for the roundness is top = 0f, bottom = 0f
25         assertEquals(0f, roundable.roundableState.topRoundness)
26         assertEquals(0f, roundable.roundableState.bottomRoundness)
27         assertEquals(false, roundable.hasRoundedCorner())
28     }
29 
30     @Test
applyRoundnessAndInvalidate_should_invalidate_targetViewnull31     fun applyRoundnessAndInvalidate_should_invalidate_targetView() {
32         roundable.applyRoundnessAndInvalidate()
33 
34         verify(targetView, times(1)).invalidate()
35     }
36 
37     @Test
requestTopRoundness_update_and_invalidate_targetViewnull38     fun requestTopRoundness_update_and_invalidate_targetView() {
39         roundable.requestTopRoundness(value = 1f, sourceType = SOURCE1)
40 
41         assertEquals(1f, roundable.roundableState.topRoundness)
42         verify(targetView, times(1)).invalidate()
43     }
44 
45     @Test
requestBottomRoundness_update_and_invalidate_targetViewnull46     fun requestBottomRoundness_update_and_invalidate_targetView() {
47         roundable.requestBottomRoundness(value = 1f, sourceType = SOURCE1)
48 
49         assertEquals(1f, roundable.roundableState.bottomRoundness)
50         verify(targetView, times(1)).invalidate()
51     }
52 
53     @Test
requestRoundness_update_and_invalidate_targetViewnull54     fun requestRoundness_update_and_invalidate_targetView() {
55         roundable.requestRoundness(top = 1f, bottom = 1f, sourceType = SOURCE1)
56 
57         assertEquals(1f, roundable.roundableState.topRoundness)
58         assertEquals(1f, roundable.roundableState.bottomRoundness)
59         verify(targetView, atLeastOnce()).invalidate()
60     }
61 
62     @Test
requestRoundnessReset_update_and_invalidate_targetViewnull63     fun requestRoundnessReset_update_and_invalidate_targetView() {
64         roundable.requestRoundness(1f, 1f, SOURCE1)
65         assertEquals(1f, roundable.roundableState.topRoundness)
66         assertEquals(1f, roundable.roundableState.bottomRoundness)
67 
68         roundable.requestRoundnessReset(sourceType = SOURCE1)
69 
70         assertEquals(0f, roundable.roundableState.topRoundness)
71         assertEquals(0f, roundable.roundableState.bottomRoundness)
72         verify(targetView, atLeastOnce()).invalidate()
73     }
74 
75     @Test
hasRoundedCorner_return_true_ifRoundnessIsGreaterThenZeronull76     fun hasRoundedCorner_return_true_ifRoundnessIsGreaterThenZero() {
77         roundable.requestRoundness(top = 1f, bottom = 1f, sourceType = SOURCE1)
78         assertEquals(true, roundable.hasRoundedCorner())
79 
80         roundable.requestRoundness(top = 1f, bottom = 0f, sourceType = SOURCE1)
81         assertEquals(true, roundable.hasRoundedCorner())
82 
83         roundable.requestRoundness(top = 0f, bottom = 1f, sourceType = SOURCE1)
84         assertEquals(true, roundable.hasRoundedCorner())
85 
86         roundable.requestRoundness(top = 0f, bottom = 0f, sourceType = SOURCE1)
87         assertEquals(false, roundable.hasRoundedCorner())
88     }
89 
90     @Test
roundness_take_maxValue_onMultipleSources_first_lowernull91     fun roundness_take_maxValue_onMultipleSources_first_lower() {
92         roundable.requestRoundness(0.1f, 0.1f, SOURCE1)
93         assertEquals(0.1f, roundable.roundableState.topRoundness)
94         assertEquals(0.1f, roundable.roundableState.bottomRoundness)
95 
96         roundable.requestRoundness(0.2f, 0.2f, SOURCE2)
97         // SOURCE1 has 0.1f - SOURCE2 has 0.2f
98         assertEquals(0.2f, roundable.roundableState.topRoundness)
99         assertEquals(0.2f, roundable.roundableState.bottomRoundness)
100     }
101 
102     @Test
roundness_take_maxValue_onMultipleSources_first_highernull103     fun roundness_take_maxValue_onMultipleSources_first_higher() {
104         roundable.requestRoundness(0.5f, 0.5f, SOURCE1)
105         assertEquals(0.5f, roundable.roundableState.topRoundness)
106         assertEquals(0.5f, roundable.roundableState.bottomRoundness)
107 
108         roundable.requestRoundness(0.1f, 0.1f, SOURCE2)
109         // SOURCE1 has 0.5f - SOURCE2 has 0.1f
110         assertEquals(0.5f, roundable.roundableState.topRoundness)
111         assertEquals(0.5f, roundable.roundableState.bottomRoundness)
112     }
113 
114     @Test
roundness_take_maxValue_onMultipleSources_first_higher_second_stepnull115     fun roundness_take_maxValue_onMultipleSources_first_higher_second_step() {
116         roundable.requestRoundness(0.1f, 0.1f, SOURCE1)
117         assertEquals(0.1f, roundable.roundableState.topRoundness)
118         assertEquals(0.1f, roundable.roundableState.bottomRoundness)
119 
120         roundable.requestRoundness(0.2f, 0.2f, SOURCE2)
121         // SOURCE1 has 0.1f - SOURCE2 has 0.2f
122         assertEquals(0.2f, roundable.roundableState.topRoundness)
123         assertEquals(0.2f, roundable.roundableState.bottomRoundness)
124 
125         roundable.requestRoundness(0.3f, 0.3f, SOURCE1)
126         // SOURCE1 has 0.3f - SOURCE2 has 0.2f
127         assertEquals(0.3f, roundable.roundableState.topRoundness)
128         assertEquals(0.3f, roundable.roundableState.bottomRoundness)
129     }
130 
131     @Test
roundness_take_maxValue_onMultipleSources_first_lower_second_stepnull132     fun roundness_take_maxValue_onMultipleSources_first_lower_second_step() {
133         roundable.requestRoundness(0.5f, 0.5f, SOURCE1)
134         assertEquals(0.5f, roundable.roundableState.topRoundness)
135         assertEquals(0.5f, roundable.roundableState.bottomRoundness)
136 
137         roundable.requestRoundness(0.2f, 0.2f, SOURCE2)
138         // SOURCE1 has 0.5f - SOURCE2 has 0.2f
139         assertEquals(0.5f, roundable.roundableState.topRoundness)
140         assertEquals(0.5f, roundable.roundableState.bottomRoundness)
141 
142         roundable.requestRoundness(0.1f, 0.1f, SOURCE1)
143         // SOURCE1 has 0.1f - SOURCE2 has 0.2f
144         assertEquals(0.2f, roundable.roundableState.topRoundness)
145         assertEquals(0.2f, roundable.roundableState.bottomRoundness)
146     }
147 
148     @Test
getCornerRadii_radius_maxed_to_heightnull149     fun getCornerRadii_radius_maxed_to_height() {
150         whenever(targetView.height).thenReturn(10)
151         roundable.requestRoundness(1f, 1f, SOURCE1)
152 
153         assertCornerRadiiEquals(5f, 5f)
154     }
155 
156     @Test
getCornerRadii_topRadius_maxed_to_heightnull157     fun getCornerRadii_topRadius_maxed_to_height() {
158         whenever(targetView.height).thenReturn(5)
159         roundable.requestRoundness(1f, 0f, SOURCE1)
160 
161         assertCornerRadiiEquals(5f, 0f)
162     }
163 
164     @Test
getCornerRadii_bottomRadius_maxed_to_heightnull165     fun getCornerRadii_bottomRadius_maxed_to_height() {
166         whenever(targetView.height).thenReturn(5)
167         roundable.requestRoundness(0f, 1f, SOURCE1)
168 
169         assertCornerRadiiEquals(0f, 5f)
170     }
171 
172     @Test
getCornerRadii_radii_keptnull173     fun getCornerRadii_radii_kept() {
174         whenever(targetView.height).thenReturn(100)
175         roundable.requestRoundness(1f, 1f, SOURCE1)
176 
177         assertCornerRadiiEquals(MAX_RADIUS, MAX_RADIUS)
178     }
179 
assertCornerRadiiEqualsnull180     private fun assertCornerRadiiEquals(top: Float, bottom: Float) {
181         assertEquals("topCornerRadius", top, roundable.topCornerRadius)
182         assertEquals("bottomCornerRadius", bottom, roundable.bottomCornerRadius)
183     }
184 
185     class FakeRoundable(targetView: View, radius: Float = MAX_RADIUS) : Roundable {
186         override val roundableState =
187             RoundableState(targetView = targetView, roundable = this, maxRadius = radius)
188 
189         override val clipHeight: Int
190             get() = roundableState.targetView.height
191     }
192 
193     companion object {
194         private const val MAX_RADIUS = 10f
195         private val SOURCE1 = SourceType.from("Source1")
196         private val SOURCE2 = SourceType.from("Source2")
197     }
198 }
199