blob: 2042faba2b3a1d11cde8f3456ee36d9bf39b4fcf [file] [log] [blame]
Robert Snoeberger57872e32018-11-06 15:22:01 -05001/*
2 * Copyright (C) 2018 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
17package com.android.systemui.statusbar.phone;
18
19import static com.google.common.truth.Truth.assertThat;
20
Robert Snoeberger57872e32018-11-06 15:22:01 -050021import android.testing.AndroidTestingRunner;
22import android.testing.TestableLooper;
23
Brett Chabot84151d92019-02-27 15:37:59 -080024import androidx.test.filters.SmallTest;
25
Robert Snoeberger57872e32018-11-06 15:22:01 -050026import com.android.systemui.SysuiTestCase;
27
28import org.junit.Before;
29import org.junit.Test;
30import org.junit.runner.RunWith;
31
32@SmallTest
33@RunWith(AndroidTestingRunner.class)
Jason Monka716bac2018-12-05 15:48:21 -050034@TestableLooper.RunWithLooper
Robert Snoeberger57872e32018-11-06 15:22:01 -050035public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
36
37 private static final int SCREEN_HEIGHT = 2000;
Robert Snoeberger69956802019-04-16 16:55:21 -040038 private static final int PREFERRED_CLOCK_Y = SCREEN_HEIGHT / 2;
Robert Snoeberger57872e32018-11-06 15:22:01 -050039 private static final int EMPTY_MARGIN = 0;
40 private static final int EMPTY_HEIGHT = 0;
Robert Snoeberger57872e32018-11-06 15:22:01 -050041 private static final float ZERO_DRAG = 0.f;
42 private static final float OPAQUE = 1.f;
43 private static final float TRANSPARENT = 0.f;
Robert Snoeberger168949a2019-04-18 09:39:42 -040044 private static final boolean HAS_CUSTOM_CLOCK = false;
45 private static final boolean HAS_VISIBLE_NOTIFS = false;
Robert Snoeberger57872e32018-11-06 15:22:01 -050046
47 private KeyguardClockPositionAlgorithm mClockPositionAlgorithm;
48 private KeyguardClockPositionAlgorithm.Result mClockPosition;
49 private int mNotificationStackHeight;
50 private float mPanelExpansion;
51 private int mKeyguardStatusHeight;
52 private float mDark;
Robert Snoeberger168949a2019-04-18 09:39:42 -040053 private int mPreferredClockY;
54 private boolean mHasCustomClock;
55 private boolean mHasVisibleNotifs;
Robert Snoeberger57872e32018-11-06 15:22:01 -050056
57 @Before
58 public void setUp() {
59 mClockPositionAlgorithm = new KeyguardClockPositionAlgorithm();
60 mClockPosition = new KeyguardClockPositionAlgorithm.Result();
Robert Snoeberger168949a2019-04-18 09:39:42 -040061
62 mPreferredClockY = PREFERRED_CLOCK_Y;
63 mHasCustomClock = HAS_CUSTOM_CLOCK;
64 mHasVisibleNotifs = HAS_VISIBLE_NOTIFS;
Robert Snoeberger57872e32018-11-06 15:22:01 -050065 }
66
67 @Test
68 public void clockPositionMiddleOfScreenOnAOD() {
69 // GIVEN on AOD and both stack scroll and clock have 0 height
70 givenAOD();
71 mNotificationStackHeight = EMPTY_HEIGHT;
72 mKeyguardStatusHeight = EMPTY_HEIGHT;
73 // WHEN the clock position algorithm is run
74 positionClock();
75 // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2).
76 assertThat(mClockPosition.clockY).isEqualTo(1000);
77 // AND the clock is opaque and positioned on the left.
78 assertThat(mClockPosition.clockX).isEqualTo(0);
79 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
80 }
81
82 @Test
83 public void clockPositionAdjustsForKeyguardStatusOnAOD() {
84 // GIVEN on AOD with a clock of height 100
85 givenAOD();
86 mNotificationStackHeight = EMPTY_HEIGHT;
87 mKeyguardStatusHeight = 100;
88 // WHEN the clock position algorithm is run
89 positionClock();
90 // THEN the clock Y position adjusts for the clock height (SCREEN_HEIGHT / 2 - 100).
91 assertThat(mClockPosition.clockY).isEqualTo(900);
92 // AND the clock is opaque and positioned on the left.
93 assertThat(mClockPosition.clockX).isEqualTo(0);
94 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
95 }
96
97 @Test
98 public void clockPositionLargeClockOnAOD() {
99 // GIVEN on AOD with a full screen clock
100 givenAOD();
101 mNotificationStackHeight = EMPTY_HEIGHT;
102 mKeyguardStatusHeight = SCREEN_HEIGHT;
103 // WHEN the clock position algorithm is run
104 positionClock();
Robert Snoeberger10b63532018-11-07 16:14:11 -0500105 // THEN the clock Y position doesn't overflow the screen.
106 assertThat(mClockPosition.clockY).isEqualTo(0);
Robert Snoeberger57872e32018-11-06 15:22:01 -0500107 // AND the clock is opaque and positioned on the left.
108 assertThat(mClockPosition.clockX).isEqualTo(0);
109 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
110 }
111
112 @Test
113 public void clockPositionMiddleOfScreenOnLockScreen() {
114 // GIVEN on lock screen with stack scroll and clock of 0 height
115 givenLockScreen();
116 mNotificationStackHeight = EMPTY_HEIGHT;
117 mKeyguardStatusHeight = EMPTY_HEIGHT;
118 // WHEN the clock position algorithm is run
119 positionClock();
120 // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2).
121 assertThat(mClockPosition.clockY).isEqualTo(1000);
122 // AND the clock is opaque and positioned on the left.
123 assertThat(mClockPosition.clockX).isEqualTo(0);
124 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
125 }
126
127 @Test
128 public void clockPositionWithStackScrollExpandOnLockScreen() {
129 // GIVEN on lock screen with stack scroll of height 500
130 givenLockScreen();
131 mNotificationStackHeight = 500;
132 mKeyguardStatusHeight = EMPTY_HEIGHT;
133 // WHEN the clock position algorithm is run
134 positionClock();
135 // THEN the clock Y position adjusts for stack scroll height ( (SCREEN_HEIGHT - 500 ) / 2).
136 assertThat(mClockPosition.clockY).isEqualTo(750);
137 // AND the clock is opaque and positioned on the left.
138 assertThat(mClockPosition.clockX).isEqualTo(0);
139 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
140 }
141
142 @Test
143 public void clockPositionWithPartialDragOnLockScreen() {
144 // GIVEN dragging up on lock screen
145 givenLockScreen();
146 mNotificationStackHeight = EMPTY_HEIGHT;
147 mKeyguardStatusHeight = EMPTY_HEIGHT;
148 mPanelExpansion = 0.5f;
149 // WHEN the clock position algorithm is run
150 positionClock();
151 // THEN the clock Y position adjusts with drag gesture.
152 assertThat(mClockPosition.clockY).isLessThan(1000);
153 // AND the clock is positioned on the left and not fully opaque.
154 assertThat(mClockPosition.clockX).isEqualTo(0);
155 assertThat(mClockPosition.clockAlpha).isLessThan(OPAQUE);
156 }
157
158 @Test
159 public void clockPositionWithFullDragOnLockScreen() {
160 // GIVEN the lock screen is dragged up
161 givenLockScreen();
162 mNotificationStackHeight = EMPTY_HEIGHT;
163 mKeyguardStatusHeight = EMPTY_HEIGHT;
164 mPanelExpansion = 0.f;
165 // WHEN the clock position algorithm is run
166 positionClock();
167 // THEN the clock is transparent.
168 assertThat(mClockPosition.clockAlpha).isEqualTo(TRANSPARENT);
169 }
170
171 @Test
172 public void largeClockOnLockScreenIsTransparent() {
173 // GIVEN on lock screen with a full screen clock
174 givenLockScreen();
175 mNotificationStackHeight = EMPTY_HEIGHT;
176 mKeyguardStatusHeight = SCREEN_HEIGHT;
177 // WHEN the clock position algorithm is run
178 positionClock();
179 // THEN the clock is transparent
180 assertThat(mClockPosition.clockAlpha).isEqualTo(TRANSPARENT);
181 }
182
Robert Snoeberger6067dfb2018-11-27 15:50:13 -0500183 @Test
184 public void notifPositionMiddleOfScreenOnAOD() {
185 // GIVEN on AOD and both stack scroll and clock have 0 height
186 givenAOD();
187 mNotificationStackHeight = EMPTY_HEIGHT;
188 mKeyguardStatusHeight = EMPTY_HEIGHT;
189 // WHEN the position algorithm is run
190 positionClock();
191 // THEN the notif padding is half of the screen (SCREEN_HEIGHT / 2).
192 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(1000);
193 }
194
195 @Test
196 public void notifPositionIndependentOfKeyguardStatusHeightOnAOD() {
197 // GIVEN on AOD and clock has a nonzero height
198 givenAOD();
199 mNotificationStackHeight = EMPTY_HEIGHT;
200 mKeyguardStatusHeight = 100;
201 // WHEN the position algorithm is run
202 positionClock();
203 // THEN the notif padding is half of the screen (SCREEN_HEIGHT / 2).
204 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(1000);
205 }
206
207 @Test
208 public void notifPositionWithLargeClockOnAOD() {
209 // GIVEN on AOD and clock has a nonzero height
210 givenAOD();
211 mNotificationStackHeight = EMPTY_HEIGHT;
212 mKeyguardStatusHeight = SCREEN_HEIGHT;
213 // WHEN the position algorithm is run
214 positionClock();
215 // THEN the notif padding is, unfortunately, the entire screen.
216 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(SCREEN_HEIGHT);
217 }
218
219 @Test
Robert Snoeberger6067dfb2018-11-27 15:50:13 -0500220 public void notifPositionMiddleOfScreenOnLockScreen() {
221 // GIVEN on lock screen and both stack scroll and clock have 0 height
222 givenLockScreen();
223 mNotificationStackHeight = EMPTY_HEIGHT;
224 mKeyguardStatusHeight = EMPTY_HEIGHT;
225 // WHEN the position algorithm is run
226 positionClock();
227 // THEN the notif padding is half of the screen (SCREEN_HEIGHT / 2).
228 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(1000);
229 }
230
231 @Test
232 public void notifPositionAdjustsForStackHeightOnLockScreen() {
233 // GIVEN on lock screen and stack scroller has a nonzero height
234 givenLockScreen();
235 mNotificationStackHeight = 500;
236 mKeyguardStatusHeight = EMPTY_HEIGHT;
237 // WHEN the position algorithm is run
238 positionClock();
239 // THEN the notif padding adjusts for the expanded notif stack.
240 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(750);
241 }
242
243 @Test
244 public void notifPositionAdjustsForClockHeightOnLockScreen() {
245 // GIVEN on lock screen and stack scroller has a nonzero height
246 givenLockScreen();
247 mNotificationStackHeight = EMPTY_HEIGHT;
248 mKeyguardStatusHeight = 200;
249 // WHEN the position algorithm is run
250 positionClock();
251 // THEN the notif padding adjusts for both clock and notif stack.
252 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(1000);
253 }
254
255 @Test
256 public void notifPositionAdjustsForStackHeightAndClockHeightOnLockScreen() {
257 // GIVEN on lock screen and stack scroller has a nonzero height
258 givenLockScreen();
259 mNotificationStackHeight = 500;
260 mKeyguardStatusHeight = 200;
261 // WHEN the position algorithm is run
262 positionClock();
263 // THEN the notif padding adjusts for both clock and notif stack.
264 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(810);
265 }
266
267 @Test
268 public void notifPositionWithLargeClockOnLockScreen() {
269 // GIVEN on lock screen and clock has a nonzero height
270 givenLockScreen();
271 mNotificationStackHeight = EMPTY_HEIGHT;
272 mKeyguardStatusHeight = SCREEN_HEIGHT;
273 // WHEN the position algorithm is run
274 positionClock();
275 // THEN the notif padding is half of the screen (SCREEN_HEIGHT / 2).
276 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(1000);
277 }
278
279 @Test
280 public void notifPositionWithFullDragOnLockScreen() {
281 // GIVEN the lock screen is dragged up
282 givenLockScreen();
283 mNotificationStackHeight = EMPTY_HEIGHT;
284 mKeyguardStatusHeight = EMPTY_HEIGHT;
285 mPanelExpansion = 0.f;
286 // WHEN the clock position algorithm is run
287 positionClock();
288 // THEN the notif padding is zero.
289 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(0);
290 }
291
292 @Test
293 public void notifPositionWithLargeClockFullDragOnLockScreen() {
294 // GIVEN the lock screen is dragged up and a full screen clock
295 givenLockScreen();
296 mNotificationStackHeight = EMPTY_HEIGHT;
297 mKeyguardStatusHeight = SCREEN_HEIGHT;
298 mPanelExpansion = 0.f;
299 // WHEN the clock position algorithm is run
300 positionClock();
301 // THEN the notif padding is zero.
302 assertThat(mClockPosition.stackScrollerPadding).isEqualTo(0);
303 }
304
Robert Snoeberger168949a2019-04-18 09:39:42 -0400305 @Test
306 public void preferredCustomClockPositionNoNotifications() {
307 // GIVEN on the lock screen with a custom clock and no visible notifications
308 givenLockScreen();
309 mPreferredClockY = 100;
310 mHasCustomClock = true;
311 mHasVisibleNotifs = false;
312 // AND given empty height for clock and stack scroller
313 mNotificationStackHeight = EMPTY_HEIGHT;
314 mKeyguardStatusHeight = EMPTY_HEIGHT;
315 // WHEN the clock position algorithm is run
316 positionClock();
317 // THEN the clock Y position is the preferred Y position.
318 assertThat(mClockPosition.clockY).isEqualTo(100);
Robert Snoeberger4cbd1592019-04-24 14:20:38 -0400319 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
Robert Snoeberger168949a2019-04-18 09:39:42 -0400320 }
321
322 @Test
323 public void preferredDefaultClockPositionNoNotifications() {
324 // GIVEN on the lock screen with a custom clock and no visible notifications
325 givenLockScreen();
326 mPreferredClockY = 100;
327 mHasCustomClock = false;
328 mHasVisibleNotifs = false;
329 // AND given empty height for clock and stack scroller
330 mNotificationStackHeight = EMPTY_HEIGHT;
331 mKeyguardStatusHeight = EMPTY_HEIGHT;
332 // WHEN the clock position algorithm is run
333 positionClock();
334 // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2) and not
335 // preferred.
336 assertThat(mClockPosition.clockY).isEqualTo(1000);
Robert Snoeberger4cbd1592019-04-24 14:20:38 -0400337 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
Robert Snoeberger168949a2019-04-18 09:39:42 -0400338 }
339
340 @Test
341 public void preferredCustomClockPositionWithVisibleNotifications() {
342 // GIVEN on the lock screen with a custom clock and visible notifications
343 givenLockScreen();
344 mPreferredClockY = 100;
345 mHasCustomClock = true;
346 mHasVisibleNotifs = true;
347 // AND given empty height for clock and stack scroller
348 mNotificationStackHeight = EMPTY_HEIGHT;
349 mKeyguardStatusHeight = EMPTY_HEIGHT;
350 // WHEN the clock position algorithm is run
351 positionClock();
352 // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2).
353 assertThat(mClockPosition.clockY).isEqualTo(1000);
Robert Snoeberger4cbd1592019-04-24 14:20:38 -0400354 assertThat(mClockPosition.clockAlpha).isEqualTo(OPAQUE);
Robert Snoeberger168949a2019-04-18 09:39:42 -0400355 }
356
357 @Test
358 public void preferredCustomClockPositionWithVisibleNotificationsOnAod() {
359 // GIVEN on the lock screen with a custom clock and visible notifications
360 givenAOD();
361 mPreferredClockY = 100;
362 mHasCustomClock = true;
363 mHasVisibleNotifs = true;
364 // AND given empty height for clock and stack scroller
365 mNotificationStackHeight = EMPTY_HEIGHT;
366 mKeyguardStatusHeight = EMPTY_HEIGHT;
367 // WHEN the clock position algorithm is run
368 positionClock();
369 // THEN the clock Y position is the preferred Y position.
370 assertThat(mClockPosition.clockY).isEqualTo(100);
371 }
372
Robert Snoeberger57872e32018-11-06 15:22:01 -0500373 private void givenAOD() {
374 mPanelExpansion = 1.f;
375 mDark = 1.f;
376 }
377
378 private void givenLockScreen() {
379 mPanelExpansion = 1.f;
380 mDark = 0.f;
381 }
382
383 private void positionClock() {
384 mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
Robert Snoeberger168949a2019-04-18 09:39:42 -0400385 mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mPreferredClockY,
Selim Cinekb0fada62019-06-17 19:03:59 -0700386 mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
387 0 /* unlockedStackScrollerPadding */);
Robert Snoeberger57872e32018-11-06 15:22:01 -0500388 mClockPositionAlgorithm.run(mClockPosition);
389 }
390}