Update the computation of the widget span from size
The new computation takes into account the new cell layout border
spacing.
Change-Id: Ic20e0906bbbaaf1e53475585e2a6ca31c277e09b
Bug: 187461595
Test: Manual testing, varying the sizes in a widget
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index d977011..d18138f 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -20,8 +20,10 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
+import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.graphics.Point;
+import android.graphics.Rect;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -110,6 +112,47 @@
assertThat(info.minSpanY).isEqualTo(2);
}
+ @Test
+ public void initSpans_minResizeWidthWithCellSpacingAndWidgetInset_shouldInitializeMinSpans() {
+ InvariantDeviceProfile idp = createIDP();
+ DeviceProfile dp = idp.supportedProfiles.get(0);
+ Rect padding = new Rect();
+ AppWidgetHostView.getDefaultPaddingForWidget(mContext, null, padding);
+ int maxPadding = Math.max(Math.max(padding.left, padding.right),
+ Math.max(padding.top, padding.bottom));
+ dp.cellLayoutBorderSpacingPx = maxPadding + 1;
+ Mockito.when(dp.shouldInsetWidgets()).thenReturn(true);
+
+ LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minResizeWidth = CELL_SIZE * 2 + maxPadding;
+ info.minResizeHeight = CELL_SIZE * 2 + maxPadding;
+
+ info.initSpans(mContext, idp);
+
+ assertThat(info.minSpanX).isEqualTo(2);
+ assertThat(info.minSpanY).isEqualTo(2);
+ }
+
+ @Test
+ public void initSpans_minResizeWidthWithCellSpacingAndNoWidgetInset_shouldInitializeMinSpans() {
+ InvariantDeviceProfile idp = createIDP();
+ DeviceProfile dp = idp.supportedProfiles.get(0);
+ Rect padding = new Rect();
+ AppWidgetHostView.getDefaultPaddingForWidget(mContext, null, padding);
+ int maxPadding = Math.max(Math.max(padding.left, padding.right),
+ Math.max(padding.top, padding.bottom));
+ dp.cellLayoutBorderSpacingPx = maxPadding - 1;
+ Mockito.when(dp.shouldInsetWidgets()).thenReturn(false);
+ LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minResizeWidth = CELL_SIZE * 2 + maxPadding;
+ info.minResizeHeight = CELL_SIZE * 2 + maxPadding;
+
+ info.initSpans(mContext, idp);
+
+ assertThat(info.minSpanX).isEqualTo(3);
+ assertThat(info.minSpanY).isEqualTo(3);
+ }
+
private InvariantDeviceProfile createIDP() {
DeviceProfile profile = Mockito.mock(DeviceProfile.class);
doAnswer(i -> {
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index 53b5fec..14108f6 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -67,61 +67,86 @@
}
public void initSpans(Context context, InvariantDeviceProfile idp) {
- // Always assume we're working with the smallest span to make sure we
- // reserve enough space in both orientations.
- float smallestCellWidth = Float.MAX_VALUE;
- float smallestCellHeight = Float.MAX_VALUE;
+ int minSpanX = 0;
+ int minSpanY = 0;
+ int maxSpanX = idp.numColumns;
+ int maxSpanY = idp.numRows;
+ int spanX = 0;
+ int spanY = 0;
+
+ Rect widgetPadding = new Rect();
+ Rect localPadding = new Rect();
+ AppWidgetHostView.getDefaultPaddingForWidget(context, provider, widgetPadding);
Point cellSize = new Point();
- boolean isWidgetPadded = false;
for (DeviceProfile dp : idp.supportedProfiles) {
dp.getCellSize(cellSize);
- smallestCellWidth = Math.min(smallestCellWidth, cellSize.x);
- smallestCellHeight = Math.min(smallestCellHeight, cellSize.y);
- isWidgetPadded = isWidgetPadded || !dp.shouldInsetWidgets();
+ // We want to account for the extra amount of padding that we are adding to the widget
+ // to ensure that it gets the full amount of space that it has requested.
+ // If grids supports insetting widgets, we do not account for widget padding.
+ if (dp.shouldInsetWidgets()) {
+ localPadding.setEmpty();
+ } else {
+ localPadding.set(widgetPadding);
+ }
+ minSpanX = Math.max(minSpanX,
+ getSpanX(localPadding, minResizeWidth, dp.cellLayoutBorderSpacingPx,
+ cellSize.x));
+ minSpanY = Math.max(minSpanY,
+ getSpanY(localPadding, minResizeHeight, dp.cellLayoutBorderSpacingPx,
+ cellSize.y));
+
+ if (ATLEAST_S) {
+ if (maxResizeWidth > 0) {
+ maxSpanX = Math.min(maxSpanX,
+ getSpanX(localPadding, maxResizeWidth, dp.cellLayoutBorderSpacingPx,
+ cellSize.x));
+ }
+ if (maxResizeHeight > 0) {
+ maxSpanY = Math.min(maxSpanY,
+ getSpanY(localPadding, maxResizeHeight, dp.cellLayoutBorderSpacingPx,
+ cellSize.y));
+ }
+ }
+
+ spanX = Math.max(spanX,
+ getSpanX(localPadding, minWidth, dp.cellLayoutBorderSpacingPx, cellSize.x));
+ spanY = Math.max(spanY,
+ getSpanY(localPadding, minHeight, dp.cellLayoutBorderSpacingPx, cellSize.y));
}
- // We want to account for the extra amount of padding that we are adding to the widget
- // to ensure that it gets the full amount of space that it has requested.
- // If grids supports insetting widgets, we do not account for widget padding.
- Rect widgetPadding = new Rect();
- if (isWidgetPadded) {
- AppWidgetHostView.getDefaultPaddingForWidget(context, provider, widgetPadding);
+ if (ATLEAST_S) {
+ // Ensures maxSpan >= minSpan
+ maxSpanX = Math.max(maxSpanX, minSpanX);
+ maxSpanY = Math.max(maxSpanY, minSpanY);
+
+ // Use targetCellWidth/Height if it is within the min/max ranges.
+ // Otherwise, use the span of minWidth/Height.
+ if (targetCellWidth >= minSpanX && targetCellWidth <= maxSpanX
+ && targetCellHeight >= minSpanY && targetCellHeight <= maxSpanY) {
+ spanX = targetCellWidth;
+ spanY = targetCellHeight;
+ }
}
- minSpanX = getSpanX(widgetPadding, minResizeWidth, smallestCellWidth);
- minSpanY = getSpanY(widgetPadding, minResizeHeight, smallestCellHeight);
-
- // Use maxResizeWidth/Height if they are defined and we're on S or above.
- maxSpanX =
- (ATLEAST_S && maxResizeWidth > 0)
- ? getSpanX(widgetPadding, maxResizeWidth, smallestCellWidth)
- : idp.numColumns;
- maxSpanY =
- (ATLEAST_S && maxResizeHeight > 0)
- ? getSpanY(widgetPadding, maxResizeHeight, smallestCellHeight)
- : idp.numRows;
-
- // Use targetCellWidth/Height if it is within the min/max ranges and we're on S or above.
- // Otherwise, fall back to minWidth/Height.
- if (ATLEAST_S && targetCellWidth >= minSpanX && targetCellWidth <= maxSpanX
- && targetCellHeight >= minSpanY && targetCellHeight <= maxSpanY) {
- spanX = targetCellWidth;
- spanY = targetCellHeight;
- } else {
- spanX = getSpanX(widgetPadding, minWidth, smallestCellWidth);
- spanY = getSpanY(widgetPadding, minHeight, smallestCellHeight);
- }
+ this.minSpanX = minSpanX;
+ this.minSpanY = minSpanY;
+ this.maxSpanX = maxSpanX;
+ this.maxSpanY = maxSpanY;
+ this.spanX = spanX;
+ this.spanY = spanY;
}
- private int getSpanX(Rect widgetPadding, int widgetWidth, float cellWidth) {
+ private int getSpanX(Rect widgetPadding, int widgetWidth, int cellSpacing, float cellWidth) {
return Math.max(1, (int) Math.ceil(
- (widgetWidth + widgetPadding.left + widgetPadding.right) / cellWidth));
+ (widgetWidth + widgetPadding.left + widgetPadding.right + cellSpacing) / (cellWidth
+ + cellSpacing)));
}
- private int getSpanY(Rect widgetPadding, int widgetHeight, float cellHeight) {
+ private int getSpanY(Rect widgetPadding, int widgetHeight, int cellSpacing, float cellHeight) {
return Math.max(1, (int) Math.ceil(
- (widgetHeight + widgetPadding.top + widgetPadding.bottom) / cellHeight));
+ (widgetHeight + widgetPadding.top + widgetPadding.bottom + cellSpacing) / (
+ cellHeight + cellSpacing)));
}
public String getLabel(PackageManager packageManager) {