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.decor 18 19 import android.graphics.Color 20 import android.testing.AndroidTestingRunner 21 import android.testing.TestableLooper.RunWithLooper 22 import android.view.DisplayCutout 23 import android.view.Surface 24 import android.view.View 25 import androidx.test.filters.SmallTest 26 import com.android.systemui.R 27 import com.android.systemui.SysuiTestCase 28 import org.junit.Assert 29 import org.junit.Before 30 import org.junit.Test 31 import org.junit.runner.RunWith 32 import org.mockito.Mockito.never 33 import org.mockito.Mockito.spy 34 import org.mockito.Mockito.times 35 import org.mockito.Mockito.verify 36 37 @RunWith(AndroidTestingRunner::class) 38 @RunWithLooper(setAsMainLooper = true) 39 @SmallTest 40 class OverlayWindowTest : SysuiTestCase() { 41 42 companion object { 43 private val TEST_DECOR_VIEW_ID_1 = R.id.privacy_dot_top_left_container 44 private val TEST_DECOR_VIEW_ID_2 = R.id.privacy_dot_bottom_left_container 45 private val TEST_DECOR_VIEW_ID_3 = R.id.privacy_dot_bottom_right_container 46 } 47 48 private lateinit var overlay: OverlayWindow 49 private lateinit var decorProvider1: DecorProvider 50 private lateinit var decorProvider2: DecorProvider 51 private lateinit var decorProvider3: DecorProvider 52 53 @Before 54 fun setUp() { 55 decorProvider1 = spy( 56 PrivacyDotCornerDecorProviderImpl( 57 viewId = TEST_DECOR_VIEW_ID_1, 58 alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP, 59 alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT, 60 layoutId = R.layout.privacy_dot_top_left 61 ) 62 ) 63 decorProvider2 = spy( 64 PrivacyDotCornerDecorProviderImpl( 65 viewId = TEST_DECOR_VIEW_ID_2, 66 alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM, 67 alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT, 68 layoutId = R.layout.privacy_dot_bottom_left 69 ) 70 ) 71 decorProvider3 = spy( 72 PrivacyDotCornerDecorProviderImpl( 73 viewId = TEST_DECOR_VIEW_ID_3, 74 alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM, 75 alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT, 76 layoutId = R.layout.privacy_dot_bottom_right 77 ) 78 ) 79 overlay = OverlayWindow(mContext) 80 } 81 82 @Test 83 fun testAddProvider() { 84 @Surface.Rotation val rotation = Surface.ROTATION_270 85 overlay.addDecorProvider(decorProvider1, rotation, Color.BLACK) 86 overlay.addDecorProvider(decorProvider2, rotation, Color.YELLOW) 87 88 verify(decorProvider1, times(1)).inflateView( 89 mContext, overlay.rootView, rotation, Color.BLACK 90 ) 91 verify(decorProvider2, times(1)).inflateView( 92 mContext, overlay.rootView, rotation, Color.YELLOW 93 ) 94 95 val view1FoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_1) 96 Assert.assertNotNull(view1FoundFromRootView) 97 Assert.assertEquals(view1FoundFromRootView, overlay.getView(TEST_DECOR_VIEW_ID_1)) 98 val view2FoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_2) 99 Assert.assertNotNull(view2FoundFromRootView) 100 Assert.assertEquals(view2FoundFromRootView, overlay.getView(TEST_DECOR_VIEW_ID_2)) 101 } 102 103 @Test 104 fun testRemoveView() { 105 overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270, Color.BLACK) 106 overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270, Color.BLACK) 107 overlay.removeView(TEST_DECOR_VIEW_ID_1) 108 109 val viewFoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_1) 110 Assert.assertNull(viewFoundFromRootView) 111 Assert.assertNull(overlay.getView(TEST_DECOR_VIEW_ID_1)) 112 } 113 114 @Test 115 fun testOnReloadResAndMeasureWithoutIds() { 116 overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0, Color.BLACK) 117 overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0, Color.BLACK) 118 119 overlay.onReloadResAndMeasure( 120 reloadToken = 1, 121 rotation = Surface.ROTATION_90, 122 tintColor = Color.BLACK, 123 displayUniqueId = null 124 ) 125 verify(decorProvider1, times(1)).onReloadResAndMeasure( 126 overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, Color.BLACK, null 127 ) 128 verify(decorProvider2, times(1)).onReloadResAndMeasure( 129 overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, Color.BLACK, null 130 ) 131 } 132 133 @Test 134 fun testOnReloadResAndMeasureWithIds() { 135 overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0, Color.BLACK) 136 overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0, Color.BLACK) 137 138 overlay.onReloadResAndMeasure( 139 filterIds = arrayOf(TEST_DECOR_VIEW_ID_2), 140 reloadToken = 1, 141 rotation = Surface.ROTATION_90, 142 tintColor = Color.BLACK, 143 displayUniqueId = null 144 ) 145 verify(decorProvider1, never()).onReloadResAndMeasure( 146 overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, Color.BLACK, null 147 ) 148 verify(decorProvider2, times(1)).onReloadResAndMeasure( 149 overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, Color.BLACK, null 150 ) 151 } 152 153 @Test 154 fun testRemoveRedundantViewsWithNullParameter() { 155 overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270, Color.BLACK) 156 overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270, Color.BLACK) 157 158 overlay.removeRedundantViews(null) 159 160 Assert.assertNull(overlay.getView(TEST_DECOR_VIEW_ID_1)) 161 Assert.assertNull(overlay.rootView.findViewById(TEST_DECOR_VIEW_ID_1)) 162 Assert.assertNull(overlay.getView(TEST_DECOR_VIEW_ID_2)) 163 Assert.assertNull(overlay.rootView.findViewById(TEST_DECOR_VIEW_ID_2)) 164 } 165 166 @Test 167 fun testRemoveRedundantViewsWith2Providers() { 168 overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270, Color.BLACK) 169 overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270, Color.BLACK) 170 171 overlay.removeRedundantViews( 172 IntArray(2).apply { 173 this[0] = TEST_DECOR_VIEW_ID_3 174 this[1] = TEST_DECOR_VIEW_ID_1 175 } 176 ) 177 178 Assert.assertNotNull(overlay.getView(TEST_DECOR_VIEW_ID_1)) 179 Assert.assertNotNull(overlay.rootView.findViewById(TEST_DECOR_VIEW_ID_1)) 180 Assert.assertNull(overlay.getView(TEST_DECOR_VIEW_ID_2)) 181 Assert.assertNull(overlay.rootView.findViewById(TEST_DECOR_VIEW_ID_2)) 182 } 183 184 @Test 185 fun testHasSameProviders() { 186 Assert.assertTrue(overlay.hasSameProviders(emptyList())) 187 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider1))) 188 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2))) 189 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2, decorProvider1))) 190 191 overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0, Color.BLACK) 192 Assert.assertFalse(overlay.hasSameProviders(emptyList())) 193 Assert.assertTrue(overlay.hasSameProviders(listOf(decorProvider1))) 194 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2))) 195 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2, decorProvider1))) 196 197 overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0, Color.BLACK) 198 Assert.assertFalse(overlay.hasSameProviders(emptyList())) 199 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider1))) 200 Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2))) 201 Assert.assertTrue(overlay.hasSameProviders(listOf(decorProvider2, decorProvider1))) 202 } 203 } 204