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 package com.android.launcher3.nonquickstep
17 
18 import android.graphics.Rect
19 import androidx.test.ext.junit.runners.AndroidJUnit4
20 import androidx.test.filters.SmallTest
21 import com.android.launcher3.FakeInvariantDeviceProfileTest
22 import com.android.launcher3.util.WindowBounds
23 import com.google.common.truth.Truth.assertThat
24 import org.junit.Test
25 import org.junit.runner.RunWith
26 
27 @SmallTest
28 @RunWith(AndroidJUnit4::class)
29 class HotseatWidthCalculationTest : FakeInvariantDeviceProfileTest() {
30 
31     /**
32      * This is a case when after setting the hotseat, the space needs to be recalculated but it
33      * doesn't need to change QSB width or remove icons
34      */
35     @Test
distribute_border_space_when_space_is_enough_portraitnull36     fun distribute_border_space_when_space_is_enough_portrait() {
37         initializeVarsForTablet(isGestureMode = false)
38         windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
39         val dp = newDP()
40         dp.isTaskbarPresentInApps = true
41 
42         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
43         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
44         assertThat(dp.hotseatBorderSpace).isEqualTo(145)
45         assertThat(dp.hotseatColumnSpan).isEqualTo(6)
46         assertThat(dp.hotseatWidthPx).isEqualTo(1445)
47 
48         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
49         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
50 
51         assertThat(dp.isQsbInline).isFalse()
52         assertThat(dp.hotseatQsbWidth).isEqualTo(1435)
53     }
54 
55     /**
56      * This is a case when after setting the hotseat, and recalculating spaces it still needs to
57      * remove icons for everything to fit
58      */
59     @Test
decrease_num_of_icons_when_not_enough_space_portraitnull60     fun decrease_num_of_icons_when_not_enough_space_portrait() {
61         initializeVarsForTablet(isGestureMode = false)
62         windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
63         val dp = newDP()
64         dp.isTaskbarPresentInApps = true
65 
66         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
67         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
68         assertThat(dp.hotseatBorderSpace).isEqualTo(72)
69         assertThat(dp.hotseatColumnSpan).isEqualTo(6)
70         assertThat(dp.hotseatWidthPx).isEqualTo(1080)
71 
72         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(110)
73         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(110)
74 
75         assertThat(dp.isQsbInline).isFalse()
76         assertThat(dp.hotseatQsbWidth).isEqualTo(1070)
77     }
78 
79     /**
80      * This is a case when after setting the hotseat, the space needs to be recalculated but it
81      * doesn't need to change QSB width or remove icons
82      */
83     @Test
distribute_border_space_when_space_is_enough_landscapenull84     fun distribute_border_space_when_space_is_enough_landscape() {
85         initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
86         val dp = newDP()
87         dp.isTaskbarPresentInApps = true
88 
89         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
90         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
91         assertThat(dp.hotseatBorderSpace).isEqualTo(104)
92         assertThat(dp.hotseatColumnSpan).isEqualTo(6)
93         assertThat(dp.hotseatWidthPx).isEqualTo(1468)
94 
95         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(370)
96         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(370)
97 
98         assertThat(dp.isQsbInline).isFalse()
99         assertThat(dp.hotseatQsbWidth).isEqualTo(1455)
100     }
101 
102     /**
103      * This is a case when the hotseat spans a certain amount of columns and the nav buttons push
104      * the hotseat to the side, but not enough to change the border space.
105      */
106     @Test
nav_buttons_dont_interfere_with_required_hotseat_widthnull107     fun nav_buttons_dont_interfere_with_required_hotseat_width() {
108         initializeVarsForTablet(isGestureMode = false, isLandscape = true)
109         inv?.apply { inlineQsb = BooleanArray(4) { false } }
110         val dp = newDP()
111         dp.isTaskbarPresentInApps = true
112 
113         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
114         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
115         assertThat(dp.hotseatBorderSpace).isEqualTo(248)
116         assertThat(dp.hotseatColumnSpan).isEqualTo(6)
117         assertThat(dp.hotseatWidthPx).isEqualTo(1960)
118 
119         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(300)
120         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(300)
121 
122         assertThat(dp.isQsbInline).isFalse()
123         assertThat(dp.hotseatQsbWidth).isEqualTo(1950)
124     }
125 
126     /** This is a case when after setting the hotseat, the QSB width needs to be changed to fit */
127     @Test
decrease_qsb_when_not_enough_space_landscapenull128     fun decrease_qsb_when_not_enough_space_landscape() {
129         initializeVarsForTablet(isGestureMode = false, isLandscape = true)
130         windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
131         val dp = newDP()
132         dp.isTaskbarPresentInApps = true
133 
134         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
135         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
136         assertThat(dp.hotseatBorderSpace).isEqualTo(233)
137         assertThat(dp.hotseatColumnSpan).isEqualTo(6)
138         assertThat(dp.hotseatWidthPx).isEqualTo(1885)
139 
140         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(287)
141         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(287)
142 
143         assertThat(dp.isQsbInline).isFalse()
144         assertThat(dp.hotseatQsbWidth).isEqualTo(1875)
145     }
146 
147     /**
148      * This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
149      * it still needs to remove icons for everything to fit
150      */
151     @Test
decrease_num_of_icons_when_not_enough_space_landscapenull152     fun decrease_num_of_icons_when_not_enough_space_landscape() {
153         initializeVarsForTablet(isGestureMode = false, isLandscape = true)
154         windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
155         val dp = newDP()
156         dp.isTaskbarPresentInApps = true
157 
158         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
159         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
160         assertThat(dp.hotseatBorderSpace).isEqualTo(205)
161         assertThat(dp.hotseatColumnSpan).isEqualTo(6)
162         assertThat(dp.hotseatWidthPx).isEqualTo(1745)
163 
164         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(257)
165         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(257)
166 
167         assertThat(dp.isQsbInline).isFalse()
168         assertThat(dp.hotseatQsbWidth).isEqualTo(1735)
169     }
170 
171     @Test
border_space_should_be_zero_when_numHotseatIcons_is_smallerOrEqual_1null172     fun border_space_should_be_zero_when_numHotseatIcons_is_smallerOrEqual_1() {
173         initializeVarsForTablet(isGestureMode = false)
174         windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
175 
176         val numShownHotseatIcons = listOf(-1, 0, 1)
177         for (numHotseatIcons in numShownHotseatIcons) {
178             inv?.numShownHotseatIcons = numHotseatIcons
179 
180             val dp = newDP()
181             dp.isTaskbarPresentInApps = true
182 
183             assertThat(dp.numShownHotseatIcons).isEqualTo(numHotseatIcons)
184             assertThat(dp.hotseatBorderSpace).isEqualTo(0)
185 
186             assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
187             assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
188             assertThat(dp.hotseatQsbWidth).isEqualTo(1435)
189         }
190     }
191 
192     @Test
increase_span_when_space_between_icons_is_less_than_minimumnull193     fun increase_span_when_space_between_icons_is_less_than_minimum() {
194         initializeVarsForTwoPanel(isGestureMode = false, isLandscape = false, rows = 5, cols = 5)
195         val dp = newDP()
196         dp.isTaskbarPresentInApps = true
197 
198         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
199         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
200         assertThat(dp.hotseatBorderSpace).isEqualTo(112)
201         assertThat(dp.hotseatColumnSpan).isEqualTo(8)
202         assertThat(dp.hotseatWidthPx).isEqualTo(1383)
203 
204         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(228)
205         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(228)
206 
207         assertThat(dp.isQsbInline).isFalse()
208         assertThat(dp.hotseatQsbWidth).isEqualTo(1372)
209     }
210 }
211