1 /* 2 * Copyright (C) 2021 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.widget; 17 18 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 19 20 import static com.google.common.truth.Truth.assertThat; 21 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.Mockito.doAnswer; 24 25 import android.appwidget.AppWidgetHostView; 26 import android.content.Context; 27 import android.graphics.Point; 28 import android.graphics.Rect; 29 30 import androidx.test.ext.junit.runners.AndroidJUnit4; 31 import androidx.test.filters.SmallTest; 32 33 import com.android.launcher3.DeviceProfile; 34 import com.android.launcher3.InvariantDeviceProfile; 35 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.mockito.Mockito; 40 41 import java.util.ArrayList; 42 import java.util.Collections; 43 import java.util.List; 44 45 @SmallTest 46 @RunWith(AndroidJUnit4.class) 47 public final class LauncherAppWidgetProviderInfoTest { 48 49 private static final int SPACE_SIZE = 10; 50 private static final int CELL_SIZE = 50; 51 private static final int NUM_OF_COLS = 4; 52 private static final int NUM_OF_ROWS = 5; 53 54 private Context mContext; 55 56 @Before setUp()57 public void setUp() { 58 mContext = getApplicationContext(); 59 } 60 61 @Test initSpans_minWidthSmallerThanCellWidth_shouldInitializeSpansToOne()62 public void initSpans_minWidthSmallerThanCellWidth_shouldInitializeSpansToOne() { 63 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 64 info.minWidth = 20; 65 info.minHeight = 20; 66 InvariantDeviceProfile idp = createIDP(); 67 68 info.initSpans(mContext, idp); 69 70 assertThat(info.spanX).isEqualTo(1); 71 assertThat(info.spanY).isEqualTo(1); 72 } 73 74 @Test initSpans_minWidthLargerThanCellWidth_shouldInitializeSpans()75 public void initSpans_minWidthLargerThanCellWidth_shouldInitializeSpans() { 76 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 77 info.minWidth = 80; 78 info.minHeight = 80; 79 InvariantDeviceProfile idp = createIDP(); 80 81 info.initSpans(mContext, idp); 82 83 assertThat(info.spanX).isEqualTo(2); 84 assertThat(info.spanY).isEqualTo(2); 85 } 86 87 @Test 88 public void initSpans_minWidthLargerThanGridColumns_shouldInitializeSpansToAtMostTheGridColumns()89 initSpans_minWidthLargerThanGridColumns_shouldInitializeSpansToAtMostTheGridColumns() { 90 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 91 info.minWidth = CELL_SIZE * (NUM_OF_COLS + 1); 92 info.minHeight = 20; 93 InvariantDeviceProfile idp = createIDP(); 94 95 info.initSpans(mContext, idp); 96 97 assertThat(info.spanX).isEqualTo(NUM_OF_COLS); 98 assertThat(info.spanY).isEqualTo(1); 99 } 100 101 @Test initSpans_minHeightLargerThanGridRows_shouldInitializeSpansToAtMostTheGridRows()102 public void initSpans_minHeightLargerThanGridRows_shouldInitializeSpansToAtMostTheGridRows() { 103 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 104 info.minWidth = 20; 105 info.minHeight = 50 * (NUM_OF_ROWS + 1); 106 InvariantDeviceProfile idp = createIDP(); 107 108 info.initSpans(mContext, idp); 109 110 assertThat(info.spanX).isEqualTo(1); 111 assertThat(info.spanY).isEqualTo(NUM_OF_ROWS); 112 } 113 114 @Test initSpans_minResizeWidthUnspecified_shouldInitializeMinSpansToOne()115 public void initSpans_minResizeWidthUnspecified_shouldInitializeMinSpansToOne() { 116 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 117 InvariantDeviceProfile idp = createIDP(); 118 119 info.initSpans(mContext, idp); 120 121 assertThat(info.minSpanX).isEqualTo(1); 122 assertThat(info.minSpanY).isEqualTo(1); 123 } 124 125 @Test initSpans_minResizeWidthSmallerThanCellWidth_shouldInitializeMinSpansToOne()126 public void initSpans_minResizeWidthSmallerThanCellWidth_shouldInitializeMinSpansToOne() { 127 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 128 info.minWidth = 100; 129 info.minHeight = 100; 130 info.minResizeWidth = 20; 131 info.minResizeHeight = 20; 132 InvariantDeviceProfile idp = createIDP(); 133 134 info.initSpans(mContext, idp); 135 136 assertThat(info.minSpanX).isEqualTo(1); 137 assertThat(info.minSpanY).isEqualTo(1); 138 } 139 140 @Test initSpans_minResizeWidthLargerThanCellWidth_shouldInitializeMinSpans()141 public void initSpans_minResizeWidthLargerThanCellWidth_shouldInitializeMinSpans() { 142 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 143 info.minWidth = 100; 144 info.minHeight = 100; 145 info.minResizeWidth = 80; 146 info.minResizeHeight = 80; 147 InvariantDeviceProfile idp = createIDP(); 148 149 info.initSpans(mContext, idp); 150 151 assertThat(info.minSpanX).isEqualTo(2); 152 assertThat(info.minSpanY).isEqualTo(2); 153 } 154 155 @Test initSpans_minResizeWidthWithCellSpacingAndWidgetInset_shouldInitializeMinSpans()156 public void initSpans_minResizeWidthWithCellSpacingAndWidgetInset_shouldInitializeMinSpans() { 157 InvariantDeviceProfile idp = createIDP(); 158 DeviceProfile dp = idp.supportedProfiles.get(0); 159 Rect padding = new Rect(); 160 AppWidgetHostView.getDefaultPaddingForWidget(mContext, null, padding); 161 int maxPadding = Math.max(Math.max(padding.left, padding.right), 162 Math.max(padding.top, padding.bottom)); 163 dp.cellLayoutBorderSpacePx.x = dp.cellLayoutBorderSpacePx.y = maxPadding + 1; 164 Mockito.when(dp.shouldInsetWidgets()).thenReturn(true); 165 166 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 167 info.minWidth = CELL_SIZE * 3; 168 info.minHeight = CELL_SIZE * 3; 169 info.minResizeWidth = CELL_SIZE * 2 + maxPadding; 170 info.minResizeHeight = CELL_SIZE * 2 + maxPadding; 171 172 info.initSpans(mContext, idp); 173 174 assertThat(info.minSpanX).isEqualTo(2); 175 assertThat(info.minSpanY).isEqualTo(2); 176 } 177 178 @Test initSpans_minResizeWidthWithCellSpacingAndNoWidgetInset_shouldInitializeMinSpans()179 public void initSpans_minResizeWidthWithCellSpacingAndNoWidgetInset_shouldInitializeMinSpans() { 180 InvariantDeviceProfile idp = createIDP(); 181 DeviceProfile dp = idp.supportedProfiles.get(0); 182 Rect padding = new Rect(); 183 AppWidgetHostView.getDefaultPaddingForWidget(mContext, null, padding); 184 int maxPadding = Math.max(Math.max(padding.left, padding.right), 185 Math.max(padding.top, padding.bottom)); 186 dp.cellLayoutBorderSpacePx.x = dp.cellLayoutBorderSpacePx.y = maxPadding - 1; 187 Mockito.when(dp.shouldInsetWidgets()).thenReturn(false); 188 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 189 info.minWidth = CELL_SIZE * 3; 190 info.minHeight = CELL_SIZE * 3; 191 info.minResizeWidth = CELL_SIZE * 2 + maxPadding; 192 info.minResizeHeight = CELL_SIZE * 2 + maxPadding; 193 194 info.initSpans(mContext, idp); 195 196 assertThat(info.minSpanX).isEqualTo(3); 197 assertThat(info.minSpanY).isEqualTo(3); 198 } 199 200 @Test 201 public void initSpans_minResizeWidthHeightLargerThanMinWidth_shouldUseMinWidthHeightAsMinSpans()202 initSpans_minResizeWidthHeightLargerThanMinWidth_shouldUseMinWidthHeightAsMinSpans() { 203 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 204 info.minWidth = 20; 205 info.minHeight = 20; 206 info.minResizeWidth = 80; 207 info.minResizeHeight = 80; 208 InvariantDeviceProfile idp = createIDP(); 209 210 info.initSpans(mContext, idp); 211 212 assertThat(info.minSpanX).isEqualTo(1); 213 assertThat(info.minSpanY).isEqualTo(1); 214 } 215 216 @Test isMinSizeFulfilled_minWidthAndHeightWithinGridSize_shouldReturnTrue()217 public void isMinSizeFulfilled_minWidthAndHeightWithinGridSize_shouldReturnTrue() { 218 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 219 info.minWidth = 80; 220 info.minHeight = 80; 221 info.minResizeWidth = 50; 222 info.minResizeHeight = 50; 223 InvariantDeviceProfile idp = createIDP(); 224 225 info.initSpans(mContext, idp); 226 227 assertThat(info.isMinSizeFulfilled()).isTrue(); 228 } 229 230 @Test 231 public void isMinSizeFulfilled_minWidthAndMinResizeWidthExceededGridColumns_shouldReturnFalse()232 isMinSizeFulfilled_minWidthAndMinResizeWidthExceededGridColumns_shouldReturnFalse() { 233 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 234 info.minWidth = CELL_SIZE * (NUM_OF_COLS + 2); 235 info.minHeight = 80; 236 info.minResizeWidth = CELL_SIZE * (NUM_OF_COLS + 1); 237 info.minResizeHeight = 50; 238 InvariantDeviceProfile idp = createIDP(); 239 240 info.initSpans(mContext, idp); 241 242 assertThat(info.isMinSizeFulfilled()).isFalse(); 243 } 244 245 @Test isMinSizeFulfilled_minHeightAndMinResizeHeightExceededGridRows_shouldReturnFalse()246 public void isMinSizeFulfilled_minHeightAndMinResizeHeightExceededGridRows_shouldReturnFalse() { 247 LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); 248 info.minWidth = 80; 249 info.minHeight = CELL_SIZE * (NUM_OF_ROWS + 2); 250 info.minResizeWidth = 50; 251 info.minResizeHeight = CELL_SIZE * (NUM_OF_ROWS + 1); 252 InvariantDeviceProfile idp = createIDP(); 253 254 info.initSpans(mContext, idp); 255 256 assertThat(info.isMinSizeFulfilled()).isFalse(); 257 } 258 createIDP()259 private InvariantDeviceProfile createIDP() { 260 DeviceProfile profile = Mockito.mock(DeviceProfile.class); 261 doAnswer(i -> { 262 ((Point) i.getArgument(0)).set(CELL_SIZE, CELL_SIZE); 263 return null; 264 }).when(profile).getCellSize(any(Point.class)); 265 Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE)); 266 profile.cellLayoutBorderSpacePx = new Point(SPACE_SIZE, SPACE_SIZE); 267 Mockito.when(profile.shouldInsetWidgets()).thenReturn(true); 268 269 InvariantDeviceProfile idp = new InvariantDeviceProfile(); 270 List<DeviceProfile> supportedProfiles = new ArrayList<>(idp.supportedProfiles); 271 supportedProfiles.add(profile); 272 idp.supportedProfiles = Collections.unmodifiableList(supportedProfiles); 273 idp.numColumns = NUM_OF_COLS; 274 idp.numRows = NUM_OF_ROWS; 275 return idp; 276 } 277 } 278