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 createCellLayoutDefaultSizenull67 fun createCellLayoutDefaultSize(columns: Int, rows: Int, isMulti: Boolean): CellLayout { 68 return createCellLayout(columns, rows, isMulti) 69 } 70 createCellLayoutnull71 fun createCellLayout( 72 columns: Int, 73 rows: Int, 74 isMulti: Boolean, 75 width: Int = 1000, 76 height: Int = 1000 77 ): CellLayout { 78 val dp = getDeviceProfile() 79 // modify the device profile. 80 dp.inv.numColumns = if (isMulti) columns / 2 else columns 81 dp.inv.numRows = rows 82 dp.cellLayoutBorderSpacePx = Point(0, 0) 83 val cl = 84 if (isMulti) MultipageCellLayout(getWrappedContext(applicationContext, dp)) 85 else CellLayout(getWrappedContext(applicationContext, dp), container) 86 // I put a very large number for width and height so that all the items can fit, it doesn't 87 // need to be exact, just bigger than the sum of cell border 88 cl.measure( 89 View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), 90 View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY) 91 ) 92 return cl 93 } 94 getDeviceProfilenull95 private fun getDeviceProfile(): DeviceProfile = 96 InvariantDeviceProfile.INSTANCE[applicationContext].getDeviceProfile(applicationContext) 97 .copy(applicationContext) 98 99 private fun getWrappedContext(context: Context, dp: DeviceProfile): Context { 100 return object : ActivityContextWrapper(context) { 101 override fun getDeviceProfile(): DeviceProfile { 102 return dp 103 } 104 } 105 } 106 } 107