1 /*
2  * Copyright (C) 2021 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.keyguard.mediator
18 
19 import android.os.Handler
20 import android.os.Looper
21 import android.testing.AndroidTestingRunner
22 import androidx.test.filters.SmallTest
23 import com.android.systemui.SysuiTestCase
24 import com.android.systemui.unfold.FoldAodAnimationController
25 import com.android.systemui.unfold.SysUIUnfoldComponent
26 import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation
27 import com.android.systemui.util.mockito.capture
28 import org.junit.Before
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import org.mockito.ArgumentCaptor
32 import org.mockito.Captor
33 import org.mockito.Mock
34 import org.mockito.Mockito.`when`
35 import org.mockito.Mockito.never
36 import org.mockito.Mockito.verify
37 import org.mockito.MockitoAnnotations
38 import java.util.Optional
39 
40 @SmallTest
41 @RunWith(AndroidTestingRunner::class)
42 class ScreenOnCoordinatorTest : SysuiTestCase() {
43 
44     @Mock
45     private lateinit var runnable: Runnable
46     @Mock
47     private lateinit var unfoldComponent: SysUIUnfoldComponent
48     @Mock
49     private lateinit var foldAodAnimationController: FoldAodAnimationController
50     @Mock
51     private lateinit var unfoldAnimation: UnfoldLightRevealOverlayAnimation
52     @Captor
53     private lateinit var readyCaptor: ArgumentCaptor<Runnable>
54 
55     private val testHandler = Handler(Looper.getMainLooper())
56 
57     private lateinit var screenOnCoordinator: ScreenOnCoordinator
58 
59     @Before
60     fun setUp() {
61         MockitoAnnotations.initMocks(this)
62 
63         `when`(unfoldComponent.getUnfoldLightRevealOverlayAnimation())
64                 .thenReturn(unfoldAnimation)
65         `when`(unfoldComponent.getFoldAodAnimationController())
66                 .thenReturn(foldAodAnimationController)
67 
68         screenOnCoordinator = ScreenOnCoordinator(
69             Optional.of(unfoldComponent),
70             testHandler
71         )
72     }
73 
74     @Test
75     fun testUnfoldTransitionEnabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
76         screenOnCoordinator.onScreenTurningOn(runnable)
77 
78         onUnfoldOverlayReady()
79         onFoldAodReady()
80         waitHandlerIdle(testHandler)
81 
82         // Should be called when both unfold overlay and keyguard drawn ready
83         verify(runnable).run()
84     }
85 
86     @Test
87     fun testTasksReady_onScreenTurningOnAndTurnedOnEventsCalledTogether_callsDrawnCallback() {
88         screenOnCoordinator.onScreenTurningOn(runnable)
89         screenOnCoordinator.onScreenTurnedOn()
90 
91         onUnfoldOverlayReady()
92         onFoldAodReady()
93         waitHandlerIdle(testHandler)
94 
95         // Should be called when both unfold overlay and keyguard drawn ready
96         verify(runnable).run()
97     }
98 
99     @Test
100     fun testTasksReady_onScreenTurnedOnAndTurnedOffBeforeCompletion_doesNotCallDrawnCallback() {
101         screenOnCoordinator.onScreenTurningOn(runnable)
102         screenOnCoordinator.onScreenTurnedOn()
103         screenOnCoordinator.onScreenTurnedOff()
104 
105         onUnfoldOverlayReady()
106         onFoldAodReady()
107         waitHandlerIdle(testHandler)
108 
109         // Should not be called because this screen turning on call is not valid anymore
110         verify(runnable, never()).run()
111     }
112 
113     @Test
114     fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
115         // Recreate with empty unfoldComponent
116         screenOnCoordinator = ScreenOnCoordinator(
117             Optional.empty(),
118             testHandler
119         )
120         screenOnCoordinator.onScreenTurningOn(runnable)
121         waitHandlerIdle(testHandler)
122 
123         // Should be called when only keyguard drawn
124         verify(runnable).run()
125     }
126 
127     private fun onUnfoldOverlayReady() {
128         verify(unfoldAnimation).onScreenTurningOn(capture(readyCaptor))
129         readyCaptor.value.run()
130     }
131 
132     private fun onFoldAodReady() {
133         verify(foldAodAnimationController).onScreenTurningOn(capture(readyCaptor))
134         readyCaptor.value.run()
135     }
136 
137     private fun waitHandlerIdle(handler: Handler) {
138         handler.runWithScissors({},  /* timeout= */ 0)
139     }
140 }
141