1 /* <lambda>null2 * 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.testgenerator 18 19 import android.graphics.Point 20 import com.android.launcher3.LauncherSettings 21 import com.android.launcher3.celllayout.board.CellLayoutBoard 22 import com.android.launcher3.model.data.LauncherAppWidgetInfo 23 import com.android.launcher3.model.gridmigration.WorkspaceItem 24 import java.util.Random 25 import java.util.concurrent.atomic.AtomicInteger 26 27 /** 28 * Generate a list of WorkspaceItem's for the given test case. 29 * 30 * @param repeatAfter a number after which we would repeat the same number of icons and widgets to 31 * account for cases where the user have the same item multiple times. 32 */ 33 fun generateItemsForTest( 34 boards: List<CellLayoutBoard>, 35 repeatAfterRange: Point 36 ): List<WorkspaceItem> { 37 val id = AtomicInteger(0) 38 val widgetId = AtomicInteger(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - 1) 39 // Repeat the same appWidgetProvider and intent to have repeating widgets and icons and test 40 // that case too 41 val getIntent = { i: Int -> "Intent ${(i + repeatAfterRange.x) % repeatAfterRange.y}" } 42 val getProvider = { i: Int -> 43 "com.test/test.Provider${(i + repeatAfterRange.x) % repeatAfterRange.y }" 44 } 45 val hotseatEntries = 46 (0 until boards[0].width).map { 47 WorkspaceItem( 48 x = it, 49 y = 0, 50 spanX = 1, 51 spanY = 1, 52 id = id.getAndAdd(1), 53 screenId = it, 54 title = "Hotseat ${id.get()}", 55 appWidgetId = -1, 56 appWidgetProvider = "Hotseat icons don't have a provider", 57 intent = getIntent(id.get()), 58 type = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION, 59 container = LauncherSettings.Favorites.CONTAINER_HOTSEAT 60 ) 61 } 62 var widgetEntries = 63 boards 64 .flatMapIndexed { i, board -> board.widgets.map { Pair(i, it) } } 65 .map { 66 WorkspaceItem( 67 x = it.second.cellX, 68 y = it.second.cellY, 69 spanX = it.second.spanX, 70 spanY = it.second.spanY, 71 id = id.getAndAdd(1), 72 screenId = it.first, 73 title = "Title Widget ${id.get()}", 74 appWidgetId = widgetId.getAndAdd(-1), 75 appWidgetProvider = getProvider(id.get()), 76 intent = "Widgets don't have intent", 77 type = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET, 78 container = LauncherSettings.Favorites.CONTAINER_DESKTOP 79 ) 80 } 81 widgetEntries = widgetEntries.filter { it.appWidgetProvider.contains("Provider4") } 82 val iconEntries = 83 boards 84 .flatMapIndexed { i, board -> board.icons.map { Pair(i, it) } } 85 .map { 86 WorkspaceItem( 87 x = it.second.coord.x, 88 y = it.second.coord.y, 89 spanX = 1, 90 spanY = 1, 91 id = id.getAndAdd(1), 92 screenId = it.first, 93 title = "Title Icon ${id.get()}", 94 appWidgetId = -1, 95 appWidgetProvider = "Icons don't have providers", 96 intent = getIntent(id.get()), 97 type = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION, 98 container = LauncherSettings.Favorites.CONTAINER_DESKTOP 99 ) 100 } 101 return widgetEntries + hotseatEntries + iconEntries 102 } 103 104 data class GridMigrationUnitTestCase( 105 val boards: List<CellLayoutBoard>, 106 val destBoards: List<CellLayoutBoard>, 107 val srcSize: Point, 108 val targetSize: Point, 109 val seed: Long 110 ) 111 112 class ValidGridMigrationTestCaseGenerator(private val generator: Random) : 113 DeterministicRandomGenerator(generator) { 114 115 companion object { 116 const val MAX_BOARD_SIZE = 12 117 const val MAX_BOARD_COUNT = 10 118 const val SEED = 10342 119 } 120 generateBoardsnull121 private fun generateBoards( 122 boardGenerator: RandomBoardGenerator, 123 width: Int, 124 height: Int, 125 boardCount: Int 126 ): List<CellLayoutBoard> { 127 val boards = mutableListOf<CellLayoutBoard>() 128 for (i in 0 until boardCount) { 129 boards.add( 130 boardGenerator.generateBoard( 131 width, 132 height, 133 boardGenerator.getRandom(0, width * height) 134 ) 135 ) 136 } 137 return boards 138 } 139 generateTestCasenull140 fun generateTestCase(isDestEmpty: Boolean): GridMigrationUnitTestCase { 141 val seed = generator.nextLong() 142 val randomBoardGenerator = RandomBoardGenerator(Random(seed)) 143 val width = randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE) 144 val height = randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE) 145 val targetSize = 146 Point( 147 randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE), 148 randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE) 149 ) 150 val destBoards = 151 if (isDestEmpty) { 152 listOf() 153 } else { 154 generateBoards( 155 boardGenerator = randomBoardGenerator, 156 width = targetSize.x, 157 height = targetSize.y, 158 boardCount = randomBoardGenerator.getRandom(3, MAX_BOARD_COUNT) 159 ) 160 } 161 return GridMigrationUnitTestCase( 162 boards = 163 generateBoards( 164 boardGenerator = randomBoardGenerator, 165 width = width, 166 height = height, 167 boardCount = randomBoardGenerator.getRandom(3, MAX_BOARD_COUNT) 168 ), 169 destBoards = destBoards, 170 srcSize = Point(width, height), 171 targetSize = targetSize, 172 seed = seed 173 ) 174 } 175 } 176