• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * 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.statusbar.phone
18 
19 import android.graphics.Rect
20 import android.testing.AndroidTestingRunner
21 import android.testing.TestableLooper.RunWithLooper
22 import android.view.View
23 import android.widget.FrameLayout
24 import androidx.test.filters.SmallTest
25 import com.android.systemui.SysuiTestCase
26 import com.android.systemui.statusbar.phone.StatusBarBoundsProvider.BoundsChangeListener
27 import com.google.common.truth.Truth.assertThat
28 import org.junit.Before
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import org.mockito.Mock
32 import org.mockito.Mockito.any
33 import org.mockito.Mockito.doAnswer
34 import org.mockito.Mockito.never
35 import org.mockito.Mockito.spy
36 import org.mockito.Mockito.verify
37 import org.mockito.MockitoAnnotations
38 
39 @RunWith(AndroidTestingRunner::class)
40 @RunWithLooper(setAsMainLooper = true)
41 @SmallTest
42 class StatusBarBoundsProviderTest : SysuiTestCase() {
43 
44     companion object {
45         private val START_SIDE_BOUNDS = Rect(50, 100, 150, 200)
46         private val END_SIDE_BOUNDS = Rect(250, 300, 350, 400)
47     }
48 
49     @Mock private lateinit var boundsChangeListener: BoundsChangeListener
50 
51     private lateinit var boundsProvider: StatusBarBoundsProvider
52 
53     private lateinit var startSideContent: View
54     private lateinit var endSideContent: View
55 
56     @Before
57     fun setUp() {
58         MockitoAnnotations.initMocks(this)
59 
60         startSideContent = spy(FrameLayout(context)).apply { setBoundsOnScreen(START_SIDE_BOUNDS) }
61         endSideContent = spy(FrameLayout(context)).apply { setBoundsOnScreen(END_SIDE_BOUNDS) }
62 
63         boundsProvider =
64             StatusBarBoundsProvider(setOf(boundsChangeListener), startSideContent, endSideContent)
65     }
66 
67     @Test
68     fun visibleStartSideBounds_returnsBoundsFromStartSideContentView() {
69         assertThat(boundsProvider.visibleStartSideBounds).isEqualTo(START_SIDE_BOUNDS)
70     }
71 
72     @Test
73     fun visibleEndSideBounds_returnsBoundsFromEndSideContentView() {
74         assertThat(boundsProvider.visibleEndSideBounds).isEqualTo(END_SIDE_BOUNDS)
75     }
76 
77     @Test
78     fun startBoundsChange_afterStart_notifiesListener() {
79         boundsProvider.start()
80         val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
81 
82         startSideContent.setBoundsOnScreen(newBounds)
83 
84         verify(boundsChangeListener).onStatusBarBoundsChanged()
85     }
86 
87     @Test
88     fun startBoundsChange_beforeStart_doesNotNotifyListener() {
89         val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
90 
91         startSideContent.setBoundsOnScreen(newBounds)
92 
93         verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
94     }
95 
96     @Test
97     fun startBoundsChange_afterStop_doesNotNotifyListener() {
98         boundsProvider.start()
99         boundsProvider.stop()
100         val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
101 
102         startSideContent.setBoundsOnScreen(newBounds)
103 
104         verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
105     }
106 
107     @Test
108     fun startLayoutChange_afterStart_boundsOnScreenSame_doesNotNotifyListener() {
109         boundsProvider.start()
110         val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
111 
112         startSideContent.layout(newBounds)
113 
114         verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
115     }
116 
117     @Test
118     fun endBoundsChange_afterStart_notifiesListener() {
119         boundsProvider.start()
120         val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
121 
122         endSideContent.setBoundsOnScreen(newBounds)
123 
124         verify(boundsChangeListener).onStatusBarBoundsChanged()
125     }
126 
127     @Test
128     fun endBoundsChange_beforeStart_doesNotNotifyListener() {
129         val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
130 
131         endSideContent.setBoundsOnScreen(newBounds)
132 
133         verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
134     }
135 
136     @Test
137     fun endBoundsChange_afterStop_doesNotNotifyListener() {
138         boundsProvider.start()
139         boundsProvider.stop()
140         val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
141 
142         endSideContent.setBoundsOnScreen(newBounds)
143 
144         verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
145     }
146 
147     @Test
148     fun endLayoutChange_afterStart_boundsOnScreenSame_doesNotNotifyListener() {
149         boundsProvider.start()
150         val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
151 
152         endSideContent.layout(newBounds)
153 
154         verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
155     }
156 }
157 
Viewnull158 private fun View.setBoundsOnScreen(bounds: Rect) {
159     doAnswer { invocation ->
160             val boundsOutput = invocation.arguments[0] as Rect
161             boundsOutput.set(bounds)
162             return@doAnswer Unit
163         }
164         .`when`(this)
165         .getBoundsOnScreen(any())
166     layout(bounds.left, bounds.top, bounds.right, bounds.bottom)
167 }
168 
layoutnull169 private fun View.layout(rect: Rect) {
170     layout(rect.left, rect.top, rect.right, rect.bottom)
171 }
172