1 /*
2  * Copyright (C) 2024 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.launcher3.celllayout
18 
19 import android.content.Context
20 import android.graphics.Point
21 import android.view.View
22 import androidx.test.core.app.ApplicationProvider
23 import com.android.launcher3.CellLayout
24 import com.android.launcher3.CellLayoutContainer
25 import com.android.launcher3.DeviceProfile
26 import com.android.launcher3.InvariantDeviceProfile
27 import com.android.launcher3.MultipageCellLayout
28 import com.android.launcher3.util.ActivityContextWrapper
29 import org.junit.rules.TestWatcher
30 import org.junit.runner.Description
31 
32 /**
33  * Create CellLayouts to be used in Unit testing and make sure to set the DeviceProfile back to
34  * normal.
35  */
36 class UnitTestCellLayoutBuilderRule : TestWatcher() {
37 
38     private var prevNumColumns = 0
39     private var prevNumRows = 0
40 
41     private val applicationContext =
42         ActivityContextWrapper(ApplicationProvider.getApplicationContext())
43 
44     private val container =
45         object : CellLayoutContainer {
getCellLayoutIdnull46             override fun getCellLayoutId(cellLayout: CellLayout): Int = 0
47 
48             override fun getCellLayoutIndex(cellLayout: CellLayout): Int = 0
49 
50             override fun getPanelCount(): Int = 1
51 
52             override fun getPageDescription(pageIndex: Int): String = ""
53         }
54 
55     override fun starting(description: Description?) {
56         val dp = getDeviceProfile()
57         prevNumColumns = dp.inv.numColumns
58         prevNumRows = dp.inv.numRows
59     }
60 
finishednull61     override fun finished(description: Description?) {
62         val dp = getDeviceProfile()
63         dp.inv.numColumns = prevNumColumns
64         dp.inv.numRows = prevNumRows
65     }
66 
createCellLayoutnull67     fun createCellLayout(width: Int, height: Int, isMulti: Boolean): CellLayout {
68         val dp = getDeviceProfile()
69         // modify the device profile.
70         dp.inv.numColumns = if (isMulti) width / 2 else width
71         dp.inv.numRows = height
72         dp.cellLayoutBorderSpacePx = Point(0, 0)
73         val cl =
74             if (isMulti) MultipageCellLayout(getWrappedContext(applicationContext, dp))
75             else CellLayout(getWrappedContext(applicationContext, dp), container)
76         // I put a very large number for width and height so that all the items can fit, it doesn't
77         // need to be exact, just bigger than the sum of cell border
78         cl.measure(
79             View.MeasureSpec.makeMeasureSpec(10000, View.MeasureSpec.EXACTLY),
80             View.MeasureSpec.makeMeasureSpec(10000, View.MeasureSpec.EXACTLY)
81         )
82         return cl
83     }
84 
getDeviceProfilenull85     private fun getDeviceProfile(): DeviceProfile =
86         InvariantDeviceProfile.INSTANCE[applicationContext].getDeviceProfile(applicationContext)
87             .copy(applicationContext)
88 
89     private fun getWrappedContext(context: Context, dp: DeviceProfile): Context {
90         return object : ActivityContextWrapper(context) {
91             override fun getDeviceProfile(): DeviceProfile {
92                 return dp
93             }
94         }
95     }
96 }
97