• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17 
18 import android.graphics.PointF
19 import android.graphics.Rect
20 import android.platform.test.rule.AllowedDevices
21 import android.platform.test.rule.DeviceProduct
22 import android.platform.test.rule.IgnoreLimit
23 import android.platform.test.rule.LimitDevicesRule
24 import android.util.SparseArray
25 import com.android.launcher3.DeviceProfile.DEFAULT_DIMENSION_PROVIDER
26 import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER
27 import com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE
28 import com.android.launcher3.util.DisplayController.Info
29 import com.android.launcher3.util.SandboxApplication
30 import com.android.launcher3.util.WindowBounds
31 import java.io.PrintWriter
32 import java.io.StringWriter
33 import org.junit.Before
34 import org.junit.Rule
35 import org.mockito.kotlin.any
36 import org.mockito.kotlin.mock
37 import org.mockito.kotlin.whenever
38 
39 /**
40  * This is an abstract class for DeviceProfile tests that don't need the real Context and mock an
41  * InvariantDeviceProfile instead of creating one based on real values.
42  *
43  * For an implementation that creates InvariantDeviceProfile, use [AbstractDeviceProfileTest]
44  */
45 @AllowedDevices(allowed = [DeviceProduct.CF_PHONE])
46 @IgnoreLimit(ignoreLimit = BuildConfig.IS_STUDIO_BUILD)
47 abstract class FakeInvariantDeviceProfileTest {
48 
49     @get:Rule val context = SandboxApplication()
50 
51     protected lateinit var inv: InvariantDeviceProfile
52     protected val info = mock<Info>()
53     protected lateinit var windowBounds: WindowBounds
54     private var transposeLayoutWithOrientation = false
55     private var useTwoPanels = false
56     private var isGestureMode = true
57     private var isTransientTaskbar = true
58 
59     @Rule @JvmField val limitDevicesRule = LimitDevicesRule()
60 
61     @Before
setUpnull62     open fun setUp() {
63         // make sure to reset values
64         useTwoPanels = false
65         isGestureMode = true
66     }
67 
newDPnull68     protected fun newDP(): DeviceProfile =
69         DeviceProfile(
70             context,
71             inv,
72             info,
73             context.appComponent.wmProxy,
74             context.appComponent.themeManager,
75             windowBounds,
76             SparseArray(),
77             /*isMultiWindowMode=*/ false,
78             transposeLayoutWithOrientation,
79             useTwoPanels,
80             isGestureMode,
81             DEFAULT_PROVIDER,
82             DEFAULT_DIMENSION_PROVIDER,
83             isTransientTaskbar,
84         )
85 
86     protected fun initializeVarsForPhone(
87         isGestureMode: Boolean = true,
88         isVerticalBar: Boolean = false,
89     ) {
90         val (x, y) = if (isVerticalBar) Pair(2400, 1080) else Pair(1080, 2400)
91 
92         windowBounds =
93             WindowBounds(
94                 Rect(0, 0, x, y),
95                 Rect(
96                     if (isVerticalBar) 118 else 0,
97                     if (isVerticalBar) 74 else 118,
98                     if (!isGestureMode && isVerticalBar) 126 else 0,
99                     if (isGestureMode) 63 else if (isVerticalBar) 0 else 126,
100                 ),
101             )
102 
103         whenever(info.isTablet(any())).thenReturn(false)
104         whenever(info.getDensityDpi()).thenReturn(420)
105         whenever(info.smallestSizeDp(any())).thenReturn(411f)
106 
107         this.isGestureMode = isGestureMode
108         this.isTransientTaskbar = false
109         transposeLayoutWithOrientation = true
110 
111         inv =
112             context.appComponent.idp.apply {
113                 numRows = 5
114                 numColumns = 4
115                 numSearchContainerColumns = 4
116 
117                 iconSize = floatArrayOf(60f, 54f, 60f, 60f)
118                 iconTextSize = FloatArray(4) { 14f }
119                 deviceType = InvariantDeviceProfile.TYPE_PHONE
120 
121                 minCellSize =
122                     listOf(
123                             PointF(80f, 104f),
124                             PointF(80f, 104f),
125                             PointF(80f, 104f),
126                             PointF(80f, 104f),
127                         )
128                         .toTypedArray()
129 
130                 borderSpaces =
131                     listOf(PointF(16f, 16f), PointF(16f, 16f), PointF(16f, 16f), PointF(16f, 16f))
132                         .toTypedArray()
133 
134                 numFolderRows = intArrayOf(3, 3, 3, 3)
135                 numFolderColumns = intArrayOf(3, 3, 3, 3)
136                 folderStyle = R.style.FolderStyleDefault
137 
138                 inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_split
139 
140                 horizontalMargin = FloatArray(4) { 22f }
141 
142                 allAppsStyle = R.style.AllAppsStyleDefault
143                 allAppsCellSize =
144                     listOf(
145                             PointF(80f, 104f),
146                             PointF(80f, 104f),
147                             PointF(80f, 104f),
148                             PointF(80f, 104f),
149                         )
150                         .toTypedArray()
151                 allAppsIconSize = floatArrayOf(60f, 60f, 60f, 60f)
152                 allAppsIconTextSize = FloatArray(4) { 14f }
153                 allAppsBorderSpaces =
154                     listOf(PointF(16f, 16f), PointF(16f, 16f), PointF(16f, 16f), PointF(16f, 16f))
155                         .toTypedArray()
156 
157                 numShownHotseatIcons = 4
158 
159                 numDatabaseHotseatIcons = 4
160 
161                 hotseatBarBottomSpace = FloatArray(4) { 48f }
162                 hotseatQsbSpace = FloatArray(4) { 36f }
163 
164                 numAllAppsColumns = 4
165 
166                 isScalable = true
167 
168                 transientTaskbarIconSize = FloatArray(4) { 44f }
169                 startAlignTaskbar = BooleanArray(4) { false }
170 
171                 inlineQsb = BooleanArray(4) { false }
172 
173                 devicePaddingId = R.xml.paddings_handhelds
174 
175                 isFixedLandscape = false
176                 workspaceSpecsId = INVALID_RESOURCE_HANDLE
177                 allAppsSpecsId = INVALID_RESOURCE_HANDLE
178                 folderSpecsId = INVALID_RESOURCE_HANDLE
179                 hotseatSpecsId = INVALID_RESOURCE_HANDLE
180                 workspaceCellSpecsId = INVALID_RESOURCE_HANDLE
181                 allAppsCellSpecsId = INVALID_RESOURCE_HANDLE
182             }
183     }
184 
initializeVarsForTabletnull185     protected fun initializeVarsForTablet(
186         isLandscape: Boolean = false,
187         isGestureMode: Boolean = true,
188     ) {
189         val (x, y) = if (isLandscape) Pair(2560, 1600) else Pair(1600, 2560)
190 
191         windowBounds = WindowBounds(Rect(0, 0, x, y), Rect(0, 104, 0, 0))
192 
193         whenever(info.isTablet(any())).thenReturn(true)
194         whenever(info.getDensityDpi()).thenReturn(320)
195         whenever(info.smallestSizeDp(any())).thenReturn(800f)
196 
197         this.isGestureMode = isGestureMode
198         this.isTransientTaskbar = true
199         useTwoPanels = false
200 
201         inv =
202             context.appComponent.idp.apply {
203                 numRows = 5
204                 numColumns = 6
205                 numSearchContainerColumns = 3
206 
207                 iconSize = FloatArray(4) { 60f }
208                 iconTextSize = FloatArray(4) { 14f }
209                 deviceType = InvariantDeviceProfile.TYPE_TABLET
210 
211                 minCellSize =
212                     listOf(
213                             PointF(102f, 120f),
214                             PointF(120f, 104f),
215                             PointF(102f, 120f),
216                             PointF(102f, 120f),
217                         )
218                         .toTypedArray()
219 
220                 borderSpaces =
221                     listOf(PointF(16f, 64f), PointF(64f, 16f), PointF(16f, 64f), PointF(16f, 64f))
222                         .toTypedArray()
223 
224                 numFolderRows = intArrayOf(3, 3, 3, 3)
225                 numFolderColumns = intArrayOf(3, 3, 3, 3)
226                 folderStyle = R.style.FolderStyleDefault
227 
228                 inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5
229 
230                 horizontalMargin = floatArrayOf(54f, 120f, 54f, 54f)
231 
232                 allAppsStyle = R.style.AllAppsStyleDefault
233                 allAppsCellSize =
234                     listOf(
235                             PointF(96f, 142f),
236                             PointF(126f, 126f),
237                             PointF(96f, 142f),
238                             PointF(96f, 142f),
239                         )
240                         .toTypedArray()
241                 allAppsIconSize = FloatArray(4) { 60f }
242                 allAppsIconTextSize = FloatArray(4) { 14f }
243                 allAppsBorderSpaces =
244                     listOf(PointF(8f, 16f), PointF(16f, 16f), PointF(8f, 16f), PointF(8f, 16f))
245                         .toTypedArray()
246 
247                 numShownHotseatIcons = 6
248 
249                 numDatabaseHotseatIcons = 6
250 
251                 hotseatBarBottomSpace = floatArrayOf(36f, 40f, 36f, 36f)
252                 hotseatQsbSpace = FloatArray(4) { 32f }
253 
254                 numAllAppsColumns = 6
255 
256                 isScalable = true
257                 devicePaddingId = R.xml.paddings_6x5
258 
259                 transientTaskbarIconSize = FloatArray(4) { 44f }
260                 startAlignTaskbar = booleanArrayOf(true, false, true, true)
261 
262                 inlineQsb = booleanArrayOf(false, true, false, false)
263 
264                 devicePaddingId = R.xml.paddings_handhelds
265 
266                 isFixedLandscape = false
267                 workspaceSpecsId = INVALID_RESOURCE_HANDLE
268                 allAppsSpecsId = INVALID_RESOURCE_HANDLE
269                 folderSpecsId = INVALID_RESOURCE_HANDLE
270                 hotseatSpecsId = INVALID_RESOURCE_HANDLE
271                 workspaceCellSpecsId = INVALID_RESOURCE_HANDLE
272                 allAppsCellSpecsId = INVALID_RESOURCE_HANDLE
273             }
274     }
275 
initializeVarsForTwoPanelnull276     protected fun initializeVarsForTwoPanel(
277         isLandscape: Boolean = false,
278         isGestureMode: Boolean = true,
279         rows: Int = 4,
280         cols: Int = 4,
281     ) {
282         val (x, y) = if (isLandscape) Pair(2208, 1840) else Pair(1840, 2208)
283 
284         windowBounds = WindowBounds(Rect(0, 0, x, y), Rect(0, 110, 0, 0))
285 
286         whenever(info.isTablet(any())).thenReturn(true)
287         whenever(info.getDensityDpi()).thenReturn(420)
288         whenever(info.smallestSizeDp(any())).thenReturn(700f)
289 
290         this.isGestureMode = isGestureMode
291         this.isTransientTaskbar = true
292         useTwoPanels = true
293 
294         inv =
295             context.appComponent.idp.apply {
296                 numRows = rows
297                 numColumns = cols
298                 numSearchContainerColumns = cols
299 
300                 iconSize = floatArrayOf(60f, 52f, 52f, 60f)
301                 iconTextSize = floatArrayOf(14f, 14f, 12f, 14f)
302                 deviceType = InvariantDeviceProfile.TYPE_MULTI_DISPLAY
303 
304                 minCellSize =
305                     listOf(
306                             PointF(80f, 104f),
307                             PointF(80f, 104f),
308                             PointF(68f, 116f),
309                             PointF(80f, 102f),
310                         )
311                         .toTypedArray()
312 
313                 borderSpaces =
314                     listOf(PointF(16f, 16f), PointF(16f, 16f), PointF(16f, 20f), PointF(20f, 20f))
315                         .toTypedArray()
316 
317                 numFolderRows = intArrayOf(3, 3, 3, 3)
318                 numFolderColumns = intArrayOf(3, 3, 3, 3)
319                 folderStyle = R.style.FolderStyleDefault
320 
321                 inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_split
322 
323                 horizontalMargin = floatArrayOf(21.5f, 21.5f, 22.5f, 30.5f)
324 
325                 allAppsStyle = R.style.AllAppsStyleDefault
326                 allAppsCellSize =
327                     listOf(PointF(0f, 0f), PointF(0f, 0f), PointF(68f, 104f), PointF(80f, 104f))
328                         .toTypedArray()
329                 allAppsIconSize = floatArrayOf(60f, 60f, 52f, 60f)
330                 allAppsIconTextSize = floatArrayOf(14f, 14f, 12f, 14f)
331                 allAppsBorderSpaces =
332                     listOf(PointF(16f, 16f), PointF(16f, 16f), PointF(16f, 28f), PointF(20f, 16f))
333                         .toTypedArray()
334 
335                 numShownHotseatIcons = 6
336 
337                 numDatabaseHotseatIcons = 6
338 
339                 hotseatBarBottomSpace = floatArrayOf(48f, 48f, 36f, 20f)
340                 hotseatQsbSpace = floatArrayOf(36f, 36f, 36f, 28f)
341 
342                 numAllAppsColumns = 6
343                 numDatabaseAllAppsColumns = 6
344 
345                 isScalable = true
346 
347                 transientTaskbarIconSize = FloatArray(4) { 44f }
348                 startAlignTaskbar = BooleanArray(4) { true }
349 
350                 inlineQsb = booleanArrayOf(false, false, false, false)
351 
352                 devicePaddingId = R.xml.paddings_handhelds
353 
354                 isFixedLandscape = false
355                 workspaceSpecsId = INVALID_RESOURCE_HANDLE
356                 allAppsSpecsId = INVALID_RESOURCE_HANDLE
357                 folderSpecsId = INVALID_RESOURCE_HANDLE
358                 hotseatSpecsId = INVALID_RESOURCE_HANDLE
359                 workspaceCellSpecsId = INVALID_RESOURCE_HANDLE
360                 allAppsCellSpecsId = INVALID_RESOURCE_HANDLE
361             }
362     }
363 
dumpnull364     fun dump(dp: DeviceProfile): String {
365         val stringWriter = StringWriter()
366         val printWriter = PrintWriter(stringWriter)
367         dp.dump(context, "", printWriter)
368         printWriter.flush()
369         return stringWriter.toString()
370     }
371 }
372