1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.settings.brightness
18 
19 import android.testing.AndroidTestingRunner
20 import android.view.MotionEvent
21 import android.widget.SeekBar
22 import androidx.test.filters.SmallTest
23 import com.android.internal.logging.testing.UiEventLoggerFake
24 import com.android.settingslib.RestrictedLockUtils
25 import com.android.systemui.SysuiTestCase
26 import com.android.systemui.classifier.FalsingManagerFake
27 import com.android.systemui.statusbar.policy.BrightnessMirrorController
28 import com.android.systemui.util.mockito.any
29 import com.android.systemui.util.mockito.capture
30 import com.android.systemui.util.mockito.eq
31 import com.google.common.truth.Truth.assertThat
32 import org.junit.After
33 import org.junit.Before
34 import org.junit.Test
35 import org.junit.runner.RunWith
36 import org.mockito.ArgumentCaptor
37 import org.mockito.ArgumentMatchers.anyBoolean
38 import org.mockito.Captor
39 import org.mockito.Mock
40 import org.mockito.Mockito.isNull
41 import org.mockito.Mockito.never
42 import org.mockito.Mockito.notNull
43 import org.mockito.Mockito.times
44 import org.mockito.Mockito.verify
45 import org.mockito.MockitoAnnotations
46 import org.mockito.Mockito.`when` as whenever
47 
48 @SmallTest
49 @RunWith(AndroidTestingRunner::class)
50 class BrightnessSliderControllerTest : SysuiTestCase() {
51 
52     @Mock
53     private lateinit var brightnessSliderView: BrightnessSliderView
54     @Mock
55     private lateinit var enforcedAdmin: RestrictedLockUtils.EnforcedAdmin
56     @Mock
57     private lateinit var mirrorController: BrightnessMirrorController
58     @Mock
59     private lateinit var mirror: ToggleSlider
60     @Mock
61     private lateinit var motionEvent: MotionEvent
62     @Mock
63     private lateinit var listener: ToggleSlider.Listener
64 
65     @Captor
66     private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
67     @Mock
68     private lateinit var seekBar: SeekBar
69     private val uiEventLogger = UiEventLoggerFake()
70     private var mFalsingManager: FalsingManagerFake = FalsingManagerFake()
71 
72     private lateinit var mController: BrightnessSliderController
73 
74     @Before
75     fun setUp() {
76         MockitoAnnotations.initMocks(this)
77 
78         whenever(mirrorController.toggleSlider).thenReturn(mirror)
79         whenever(motionEvent.copy()).thenReturn(motionEvent)
80 
81         mController =
82             BrightnessSliderController(brightnessSliderView, mFalsingManager, uiEventLogger)
83         mController.init()
84         mController.setOnChangedListener(listener)
85     }
86 
87     @After
88     fun tearDown() {
89         mController.onViewDetached()
90     }
91 
92     @Test
93     fun testListenersAddedOnAttach() {
94         mController.onViewAttached()
95 
96         verify(brightnessSliderView).setOnSeekBarChangeListener(notNull())
97     }
98 
99     @Test
100     fun testAllListenersRemovedOnDettach() {
101         mController.onViewAttached()
102         mController.onViewDetached()
103 
104         verify(brightnessSliderView).setOnSeekBarChangeListener(isNull())
105         verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
106     }
107 
108     @Test
109     fun testEnforceAdminRelayed() {
110         mController.setEnforcedAdmin(enforcedAdmin)
111         verify(brightnessSliderView).setEnforcedAdmin(enforcedAdmin)
112     }
113 
114     @Test
115     fun testNullMirrorNotTrackingTouch() {
116         whenever(mirrorController.toggleSlider).thenReturn(null)
117 
118         mController.setMirrorControllerAndMirror(mirrorController)
119 
120         verify(brightnessSliderView, never()).max
121         verify(brightnessSliderView, never()).value
122         verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
123     }
124 
125     @Test
126     fun testSettingMirrorControllerReliesValuesAndSetsTouchTracking() {
127         val maxValue = 100
128         val progress = 30
129         val checked = true
130         whenever(brightnessSliderView.max).thenReturn(maxValue)
131         whenever(brightnessSliderView.value).thenReturn(progress)
132 
133         mController.setMirrorControllerAndMirror(mirrorController)
134 
135         verify(mirror).max = maxValue
136         verify(mirror).value = progress
137         verify(brightnessSliderView).setOnDispatchTouchEventListener(notNull())
138     }
139 
140     @Test
141     fun testSetMaxRelayed() {
142         mController.max = 120
143         verify(brightnessSliderView).max = 120
144     }
145 
146     @Test
147     fun testGetMax() {
148         whenever(brightnessSliderView.max).thenReturn(40)
149 
150         assertThat(mController.max).isEqualTo(40)
151     }
152 
153     @Test
154     fun testSetValue() {
155         mController.value = 30
156         verify(brightnessSliderView).value = 30
157     }
158 
159     @Test
160     fun testGetValue() {
161         whenever(brightnessSliderView.value).thenReturn(20)
162 
163         assertThat(mController.value).isEqualTo(20)
164     }
165 
166     @Test
167     fun testMirrorEventWithMirror() {
168         mController.setMirrorControllerAndMirror(mirrorController)
169 
170         mController.mirrorTouchEvent(motionEvent)
171 
172         verify(mirror).mirrorTouchEvent(motionEvent)
173         verify(brightnessSliderView, never()).dispatchTouchEvent(any(MotionEvent::class.java))
174     }
175 
176     @Test
177     fun testMirrorEventWithoutMirror_dispatchToView() {
178         mController.mirrorTouchEvent(motionEvent)
179 
180         verify(brightnessSliderView).dispatchTouchEvent(motionEvent)
181     }
182 
183     @Test
184     fun testSeekBarProgressChanged() {
185         mController.onViewAttached()
186 
187         verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
188 
189         seekBarChangeCaptor.value.onProgressChanged(seekBar, 23, true)
190 
191         verify(listener).onChanged(anyBoolean(), eq(23), eq(false))
192     }
193 
194     @Test
195     fun testSeekBarTrackingStarted() {
196         whenever(brightnessSliderView.value).thenReturn(42)
197         val event = BrightnessSliderEvent.SLIDER_STARTED_TRACKING_TOUCH
198 
199         mController.onViewAttached()
200         mController.setMirrorControllerAndMirror(mirrorController)
201         verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
202 
203         seekBarChangeCaptor.value.onStartTrackingTouch(seekBar)
204 
205         verify(listener).onChanged(eq(true), eq(42), eq(false))
206         verify(mirrorController).showMirror()
207         verify(mirrorController).setLocationAndSize(brightnessSliderView)
208         assertThat(uiEventLogger.numLogs()).isEqualTo(1)
209         assertThat(uiEventLogger.eventId(0)).isEqualTo(event.id)
210     }
211 
212     @Test
213     fun testSeekBarTrackingStopped() {
214         whenever(brightnessSliderView.value).thenReturn(23)
215         val event = BrightnessSliderEvent.SLIDER_STOPPED_TRACKING_TOUCH
216 
217         mController.onViewAttached()
218         mController.setMirrorControllerAndMirror(mirrorController)
219         verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
220 
221         seekBarChangeCaptor.value.onStopTrackingTouch(seekBar)
222 
223         verify(listener).onChanged(eq(false), eq(23), eq(true))
224         verify(mirrorController).hideMirror()
225         assertThat(uiEventLogger.numLogs()).isEqualTo(1)
226         assertThat(uiEventLogger.eventId(0)).isEqualTo(event.id)
227     }
228 }