• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * 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.model
17 
18 import android.content.ComponentName
19 import android.content.Context
20 import android.content.Intent
21 import android.graphics.Rect
22 import com.android.launcher3.InvariantDeviceProfile
23 import com.android.launcher3.LauncherAppState
24 import com.android.launcher3.LauncherSettings
25 import com.android.launcher3.model.data.WorkspaceItemInfo
26 import com.android.launcher3.util.ContentWriter
27 import com.android.launcher3.util.GridOccupancy
28 import com.android.launcher3.util.IntArray
29 import com.android.launcher3.util.IntSparseArrayMap
30 import com.android.launcher3.util.LauncherModelHelper
31 import java.util.UUID
32 
33 /** Base class for workspace related tests. */
34 abstract class AbstractWorkspaceModelTest {
35     companion object {
36         val emptyScreenSpaces = listOf(Rect(0, 0, 5, 5))
37         val fullScreenSpaces = emptyList<Rect>()
38         val nonEmptyScreenSpaces = listOf(Rect(1, 2, 3, 4))
39     }
40 
41     protected lateinit var mTargetContext: Context
42     protected lateinit var mIdp: InvariantDeviceProfile
43     protected lateinit var mAppState: LauncherAppState
44     protected lateinit var mModelHelper: LauncherModelHelper
45     protected lateinit var mExistingScreens: IntArray
46     protected lateinit var mNewScreens: IntArray
47     protected lateinit var mScreenOccupancy: IntSparseArrayMap<GridOccupancy>
48 
49     open fun setup() {
50         mModelHelper = LauncherModelHelper()
51         mTargetContext = mModelHelper.sandboxContext
52         mIdp = InvariantDeviceProfile.INSTANCE[mTargetContext]
53         mIdp.numRows = 5
54         mIdp.numColumns = mIdp.numRows
55         mAppState = LauncherAppState.getInstance(mTargetContext)
56         mExistingScreens = IntArray()
57         mScreenOccupancy = IntSparseArrayMap()
58         mNewScreens = IntArray()
59     }
60 
61     open fun tearDown() {
62         mModelHelper.destroy()
63     }
64 
65     /** Sets up workspaces with the given screen IDs with some items and a 2x2 space. */
66     fun setupWorkspaces(screenIdsWithItems: List<Int>) {
67         var nextItemId = 1
68         screenIdsWithItems.forEach { screenId ->
69             nextItemId = setupWorkspace(nextItemId, screenId, nonEmptyScreenSpaces)
70         }
71     }
72 
73     /**
74      * Sets up the given workspaces with the given spaces, and fills the remaining space with items.
75      */
76     fun setupWorkspacesWithSpaces(
77         screen0: List<Rect>? = null,
78         screen1: List<Rect>? = null,
79         screen2: List<Rect>? = null,
80         screen3: List<Rect>? = null,
81     ) = listOf(screen0, screen1, screen2, screen3).let(this::setupWithSpaces)
82 
83     private fun setupWithSpaces(workspaceSpaces: List<List<Rect>?>) {
84         var nextItemId = 1
85         workspaceSpaces.forEachIndexed { screenId, spaces ->
86             if (spaces != null) {
87                 nextItemId = setupWorkspace(nextItemId, screenId, spaces)
88             }
89         }
90     }
91 
92     private fun setupWorkspace(startId: Int, screenId: Int, spaces: List<Rect>): Int {
93         return mModelHelper.executeSimpleTask { dataModel ->
94             writeWorkspaceWithSpaces(dataModel, startId, screenId, spaces)
95         }
96     }
97 
98     private fun writeWorkspaceWithSpaces(
99         bgDataModel: BgDataModel,
100         itemStartId: Int,
101         screenId: Int,
102         spaces: List<Rect>,
103     ): Int {
104         var itemId = itemStartId
105         val occupancy = GridOccupancy(mIdp.numColumns, mIdp.numRows)
106         occupancy.markCells(0, 0, mIdp.numColumns, mIdp.numRows, true)
107         spaces.forEach { spaceRect -> occupancy.markCells(spaceRect, false) }
108         mExistingScreens.add(screenId)
109         mScreenOccupancy.append(screenId, occupancy)
110         for (x in 0 until mIdp.numColumns) {
111             for (y in 0 until mIdp.numRows) {
112                 if (!occupancy.cells[x][y]) {
113                     continue
114                 }
115                 val info = getExistingItem()
116                 info.id = itemId++
117                 info.screenId = screenId
118                 info.cellX = x
119                 info.cellY = y
120                 info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP
121                 bgDataModel.addItem(mTargetContext, info, false)
122                 val writer = ContentWriter(mTargetContext)
123                 info.writeToValues(writer)
124                 writer.put(LauncherSettings.Favorites._ID, info.id)
125                 mTargetContext.contentResolver.insert(
126                     LauncherSettings.Favorites.CONTENT_URI,
127                     writer.getValues(mTargetContext)
128                 )
129             }
130         }
131         return itemId
132     }
133 
134     fun getExistingItem() =
135         WorkspaceItemInfo().apply { intent = Intent().setComponent(ComponentName("a", "b")) }
136 
137     fun getNewItem(): WorkspaceItemInfo {
138         val itemPackage = UUID.randomUUID().toString()
139         return WorkspaceItemInfo().apply {
140             intent = Intent().setComponent(ComponentName(itemPackage, itemPackage))
141         }
142     }
143 }
144 
145 data class NewItemSpace(val screenId: Int, val cellX: Int, val cellY: Int) {
toIntArraynull146     fun toIntArray() = intArrayOf(screenId, cellX, cellY)
147 
148     companion object {
149         fun fromIntArray(array: kotlin.IntArray) = NewItemSpace(array[0], array[1], array[2])
150     }
151 }
152