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.model 17 18 import android.graphics.Rect 19 import androidx.test.ext.junit.runners.AndroidJUnit4 20 import androidx.test.filters.SmallTest 21 import com.google.common.truth.Truth.assertThat 22 import org.junit.After 23 import org.junit.Before 24 import org.junit.Test 25 import org.junit.runner.RunWith 26 27 /** Tests for [WorkspaceItemSpaceFinder] */ 28 @SmallTest 29 @RunWith(AndroidJUnit4::class) 30 class WorkspaceItemSpaceFinderTest : AbstractWorkspaceModelTest() { 31 32 private val mItemSpaceFinder = WorkspaceItemSpaceFinder() 33 34 @Before setupnull35 override fun setup() { 36 super.setup() 37 } 38 39 @After tearDownnull40 override fun tearDown() { 41 super.tearDown() 42 } 43 findSpacenull44 private fun findSpace(spanX: Int, spanY: Int): NewItemSpace = 45 mItemSpaceFinder 46 .findSpaceForItem( 47 mAppState, 48 mModelHelper.bgDataModel, 49 mExistingScreens, 50 mNewScreens, 51 spanX, 52 spanY 53 ) 54 .let { NewItemSpace.fromIntArray(it) } 55 assertRegionVacantnull56 private fun assertRegionVacant(newItemSpace: NewItemSpace, spanX: Int, spanY: Int) { 57 assertThat( 58 mScreenOccupancy[newItemSpace.screenId].isRegionVacant( 59 newItemSpace.cellX, 60 newItemSpace.cellY, 61 spanX, 62 spanY 63 ) 64 ) 65 .isTrue() 66 } 67 68 @Test justEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnFirstScreenIdnull69 fun justEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnFirstScreenId() { 70 setupWorkspacesWithSpaces( 71 // 3x2 space on screen 0, but it should be skipped 72 screen0 = listOf(Rect(2, 0, 5, 2)), 73 screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 space 74 // 2 spaces of sizes 3x2 and 2x3 75 screen2 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)), 76 ) 77 78 val spaceFound = findSpace(1, 1) 79 80 assertThat(spaceFound.screenId).isEqualTo(1) 81 assertRegionVacant(spaceFound, 1, 1) 82 } 83 84 @Test notEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnSecondScreenIdnull85 fun notEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnSecondScreenId() { 86 setupWorkspacesWithSpaces( 87 // 3x2 space on screen 0, but it should be skipped 88 screen0 = listOf(Rect(2, 0, 5, 2)), 89 screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 space 90 // 2 spaces of sizes 3x2 and 2x3 91 screen2 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)), 92 ) 93 94 // Find a larger space 95 val spaceFound = findSpace(2, 3) 96 97 assertThat(spaceFound.screenId).isEqualTo(2) 98 assertRegionVacant(spaceFound, 2, 3) 99 } 100 101 @Test notEnoughSpaceOnExistingScreens_returnNewScreenIdnull102 fun notEnoughSpaceOnExistingScreens_returnNewScreenId() { 103 setupWorkspacesWithSpaces( 104 // 3x2 space on screen 0, but it should be skipped 105 screen0 = listOf(Rect(2, 0, 5, 2)), 106 // 2 spaces of sizes 3x2 and 2x3 107 screen1 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)), 108 // 2 spaces of sizes 1x2 and 2x2 109 screen2 = listOf(Rect(1, 0, 2, 2), Rect(3, 2, 5, 4)), 110 ) 111 112 val oldScreens = mExistingScreens.clone() 113 val spaceFound = findSpace(3, 3) 114 115 assertThat(oldScreens.contains(spaceFound.screenId)).isFalse() 116 assertThat(mNewScreens.contains(spaceFound.screenId)).isTrue() 117 } 118 119 @Test firstScreenIsEmptyButSecondIsNotEmpty_returnSecondScreenIdnull120 fun firstScreenIsEmptyButSecondIsNotEmpty_returnSecondScreenId() { 121 setupWorkspacesWithSpaces( 122 // 3x2 space on screen 0, but it should be skipped 123 screen0 = listOf(Rect(2, 0, 5, 2)), 124 // empty screens are skipped 125 screen2 = listOf(Rect(2, 0, 5, 2)), // 3x2 space 126 ) 127 128 val spaceFound = findSpace(2, 1) 129 130 assertThat(spaceFound.screenId).isEqualTo(2) 131 assertRegionVacant(spaceFound, 2, 1) 132 } 133 134 @Test twoEmptyMiddleScreens_returnThirdScreennull135 fun twoEmptyMiddleScreens_returnThirdScreen() { 136 setupWorkspacesWithSpaces( 137 // 3x2 space on screen 0, but it should be skipped 138 screen0 = listOf(Rect(2, 0, 5, 2)), 139 // empty screens are skipped 140 screen3 = listOf(Rect(1, 1, 4, 4)), // 3x3 space 141 ) 142 143 val spaceFound = findSpace(2, 3) 144 145 assertThat(spaceFound.screenId).isEqualTo(3) 146 assertRegionVacant(spaceFound, 2, 3) 147 } 148 149 @Test allExistingPagesAreFull_returnNewScreenIdnull150 fun allExistingPagesAreFull_returnNewScreenId() { 151 setupWorkspacesWithSpaces( 152 // 3x2 space on screen 0, but it should be skipped 153 screen0 = listOf(Rect(2, 0, 5, 2)), 154 screen1 = fullScreenSpaces, 155 screen2 = fullScreenSpaces, 156 ) 157 158 val spaceFound = findSpace(2, 3) 159 160 assertThat(spaceFound.screenId).isEqualTo(3) 161 assertThat(mNewScreens.contains(spaceFound.screenId)).isTrue() 162 } 163 164 @Test firstTwoPagesAreFull_and_ThirdPageIsEmpty_returnThirdPagenull165 fun firstTwoPagesAreFull_and_ThirdPageIsEmpty_returnThirdPage() { 166 setupWorkspacesWithSpaces( 167 // 3x2 space on screen 0, but it should be skipped 168 screen0 = listOf(Rect(2, 0, 5, 2)), 169 screen1 = fullScreenSpaces, // full screens are skipped 170 screen2 = fullScreenSpaces, // full screens are skipped 171 screen3 = emptyScreenSpaces 172 ) 173 174 val spaceFound = findSpace(3, 1) 175 176 assertThat(spaceFound.screenId).isEqualTo(3) 177 assertRegionVacant(spaceFound, 3, 1) 178 } 179 } 180