1 /*
2  * Copyright (C) 2022 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.media.controls.ui.animation
18 
19 import android.graphics.drawable.Animatable2
20 import android.graphics.drawable.Drawable
21 import android.testing.TestableLooper
22 import androidx.test.ext.junit.runners.AndroidJUnit4
23 import androidx.test.filters.SmallTest
24 import com.android.systemui.SysuiTestCase
25 import junit.framework.Assert.assertFalse
26 import junit.framework.Assert.assertTrue
27 import org.junit.After
28 import org.junit.Before
29 import org.junit.Rule
30 import org.junit.Test
31 import org.junit.runner.RunWith
32 import org.mockito.Mock
33 import org.mockito.Mockito.never
34 import org.mockito.Mockito.times
35 import org.mockito.Mockito.verify
36 import org.mockito.Mockito.`when` as whenever
37 import org.mockito.junit.MockitoJUnit
38 
39 @SmallTest
40 @RunWith(AndroidJUnit4::class)
41 @TestableLooper.RunWithLooper(setAsMainLooper = true)
42 class AnimationBindHandlerTest : SysuiTestCase() {
43 
44     private interface Callback : () -> Unit
45     private abstract class AnimatedDrawable : Drawable(), Animatable2
46     private lateinit var handler: AnimationBindHandler
47 
48     @Mock private lateinit var animatable: AnimatedDrawable
49     @Mock private lateinit var animatable2: AnimatedDrawable
50     @Mock private lateinit var callback: Callback
51 
52     @JvmField @Rule val mockito = MockitoJUnit.rule()
53 
54     @Before
setUpnull55     fun setUp() {
56         handler = AnimationBindHandler()
57     }
58 
tearDownnull59     @After fun tearDown() {}
60 
61     @Test
registerNoAnimations_executeCallbackImmediatelynull62     fun registerNoAnimations_executeCallbackImmediately() {
63         handler.tryExecute(callback)
64         verify(callback).invoke()
65     }
66 
67     @Test
registerStoppedAnimations_executeCallbackImmediatelynull68     fun registerStoppedAnimations_executeCallbackImmediately() {
69         whenever(animatable.isRunning).thenReturn(false)
70         whenever(animatable2.isRunning).thenReturn(false)
71 
72         handler.tryExecute(callback)
73         verify(callback).invoke()
74     }
75 
76     @Test
registerRunningAnimations_executeCallbackDelayednull77     fun registerRunningAnimations_executeCallbackDelayed() {
78         whenever(animatable.isRunning).thenReturn(true)
79         whenever(animatable2.isRunning).thenReturn(true)
80 
81         handler.tryRegister(animatable)
82         handler.tryRegister(animatable2)
83         handler.tryExecute(callback)
84 
85         verify(callback, never()).invoke()
86 
87         whenever(animatable.isRunning).thenReturn(false)
88         handler.onAnimationEnd(animatable)
89         verify(callback, never()).invoke()
90 
91         whenever(animatable2.isRunning).thenReturn(false)
92         handler.onAnimationEnd(animatable2)
93         verify(callback, times(1)).invoke()
94     }
95 
96     @Test
repeatedEndCallback_executeSingleCallbacknull97     fun repeatedEndCallback_executeSingleCallback() {
98         whenever(animatable.isRunning).thenReturn(true)
99 
100         handler.tryRegister(animatable)
101         handler.tryExecute(callback)
102 
103         verify(callback, never()).invoke()
104 
105         whenever(animatable.isRunning).thenReturn(false)
106         handler.onAnimationEnd(animatable)
107         handler.onAnimationEnd(animatable)
108         handler.onAnimationEnd(animatable)
109         verify(callback, times(1)).invoke()
110     }
111 
112     @Test
registerUnregister_executeImmediatelynull113     fun registerUnregister_executeImmediately() {
114         whenever(animatable.isRunning).thenReturn(true)
115 
116         handler.tryRegister(animatable)
117         handler.unregisterAll()
118         handler.tryExecute(callback)
119 
120         verify(callback).invoke()
121     }
122 
123     @Test
updateRebindId_returnsAsExpectednull124     fun updateRebindId_returnsAsExpected() {
125         // Previous or current call is null, returns true
126         assertTrue(handler.updateRebindId(null))
127         assertTrue(handler.updateRebindId(null))
128         assertTrue(handler.updateRebindId(null))
129         assertTrue(handler.updateRebindId(10))
130         assertTrue(handler.updateRebindId(null))
131         assertTrue(handler.updateRebindId(20))
132 
133         // Different integer from prevoius, returns true
134         assertTrue(handler.updateRebindId(10))
135         assertTrue(handler.updateRebindId(20))
136 
137         // Matches previous call, returns false
138         assertFalse(handler.updateRebindId(20))
139         assertFalse(handler.updateRebindId(20))
140         assertTrue(handler.updateRebindId(10))
141         assertFalse(handler.updateRebindId(10))
142     }
143 }
144