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.statusbar
18 
19 import android.content.res.Resources
20 import android.view.CrossWindowBlurListeners
21 import android.view.SurfaceControl
22 import android.view.ViewRootImpl
23 import androidx.test.filters.SmallTest
24 import com.android.systemui.SysuiTestCase
25 import com.android.systemui.dump.DumpManager
26 import org.junit.Before
27 import org.junit.Test
28 import org.mockito.Mock
29 import org.mockito.Mockito.`when`
30 import org.mockito.Mockito.any
31 import org.mockito.Mockito.anyInt
32 import org.mockito.Mockito.clearInvocations
33 import org.mockito.Mockito.eq
34 import org.mockito.Mockito.mock
35 import org.mockito.Mockito.never
36 import org.mockito.Mockito.verify
37 import org.mockito.MockitoAnnotations
38 
39 @SmallTest
40 class BlurUtilsTest : SysuiTestCase() {
41 
42     @Mock lateinit var resources: Resources
43     @Mock lateinit var dumpManager: DumpManager
44     @Mock lateinit var transaction: SurfaceControl.Transaction
45     @Mock lateinit var crossWindowBlurListeners: CrossWindowBlurListeners
46     lateinit var blurUtils: TestableBlurUtils
47 
48     @Before
49     fun setup() {
50         MockitoAnnotations.initMocks(this)
51         blurUtils = TestableBlurUtils()
52     }
53 
54     @Test
55     fun testApplyBlur_noViewRoot_doesntCrash() {
56         blurUtils.applyBlur(null /* viewRootImple */, 10 /* radius */, false /* opaque */)
57     }
58 
59     @Test
60     fun testApplyBlur_invalidSurfaceControl() {
61         val surfaceControl = mock(SurfaceControl::class.java)
62         val viewRootImpl = mock(ViewRootImpl::class.java)
63         `when`(viewRootImpl.surfaceControl).thenReturn(surfaceControl)
64         blurUtils.applyBlur(viewRootImpl, 10 /* radius */, false /* opaque */)
65     }
66 
67     @Test
68     fun testApplyBlur_success() {
69         val radius = 10
70         val surfaceControl = mock(SurfaceControl::class.java)
71         val viewRootImpl = mock(ViewRootImpl::class.java)
72         `when`(viewRootImpl.surfaceControl).thenReturn(surfaceControl)
73         `when`(surfaceControl.isValid).thenReturn(true)
74         blurUtils.applyBlur(viewRootImpl, radius, true /* opaque */)
75         verify(transaction).setBackgroundBlurRadius(eq(surfaceControl), eq(radius))
76         verify(transaction).setOpaque(eq(surfaceControl), eq(true))
77         verify(transaction).apply()
78     }
79 
80     @Test
81     fun testApplyBlur_blurDisabled() {
82         val radius = 10
83         val surfaceControl = mock(SurfaceControl::class.java)
84         val viewRootImpl = mock(ViewRootImpl::class.java)
85         `when`(viewRootImpl.surfaceControl).thenReturn(surfaceControl)
86         `when`(surfaceControl.isValid).thenReturn(true)
87 
88         blurUtils.blursEnabled = false
89         blurUtils.applyBlur(viewRootImpl, radius, true /* opaque */)
90         verify(transaction).setOpaque(eq(surfaceControl), eq(true))
91         verify(transaction, never()).setBackgroundBlurRadius(any(), anyInt())
92         verify(transaction).apply()
93     }
94 
95     @Test
96     fun testEarlyWakeUp() {
97         val radius = 10
98         val surfaceControl = mock(SurfaceControl::class.java)
99         val viewRootImpl = mock(ViewRootImpl::class.java)
100         `when`(viewRootImpl.surfaceControl).thenReturn(surfaceControl)
101         `when`(surfaceControl.isValid).thenReturn(true)
102         blurUtils.applyBlur(viewRootImpl, radius, true /* opaque */)
103         verify(transaction).setEarlyWakeupStart()
104         clearInvocations(transaction)
105         blurUtils.applyBlur(viewRootImpl, 0, true /* opaque */)
106         verify(transaction).setEarlyWakeupEnd()
107     }
108 
109     inner class TestableBlurUtils : BlurUtils(resources, crossWindowBlurListeners, dumpManager) {
110         var blursEnabled = true
111 
112         override fun supportsBlursOnWindows(): Boolean {
113             return blursEnabled
114         }
115 
116         override fun createTransaction(): SurfaceControl.Transaction {
117             return transaction
118         }
119     }
120 }