From 1d47d8c705928870badfb510056ec2b16f3a093c Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Tue, 1 Jun 2021 22:58:37 +0100 Subject: [PATCH] Use grid size as the upper bound for widgets' default size in initSpans Test: In Pixel 4, drag a monthly view Google calendar widget to a new home page from the full widgets picker. The widget outline is correctly shown. Bug: 189060113 Change-Id: I33113b29cc8923098de95f1d5eb14c2b02429de1 --- .../LauncherAppWidgetProviderInfoTest.java | 74 +++++++++++++++++++ .../widget/LauncherAppWidgetProviderInfo.java | 47 +++++++++++- .../android/launcher3/model/WidgetsModel.java | 8 +- 3 files changed, 122 insertions(+), 7 deletions(-) diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java index d18138f8d2..c7286e5676 100644 --- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java +++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java @@ -40,6 +40,8 @@ import org.robolectric.RuntimeEnvironment; public final class LauncherAppWidgetProviderInfoTest { private static final int CELL_SIZE = 50; + private static final int NUM_OF_COLS = 4; + private static final int NUM_OF_ROWS = 5; private Context mContext; @@ -75,6 +77,33 @@ public final class LauncherAppWidgetProviderInfoTest { assertThat(info.spanY).isEqualTo(2); } + @Test + public void + initSpans_minWidthLargerThanGridColumns_shouldInitializeSpansToAtMostTheGridColumns() { + LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); + info.minWidth = CELL_SIZE * (NUM_OF_COLS + 1); + info.minHeight = 20; + InvariantDeviceProfile idp = createIDP(); + + info.initSpans(mContext, idp); + + assertThat(info.spanX).isEqualTo(NUM_OF_COLS); + assertThat(info.spanY).isEqualTo(1); + } + + @Test + public void initSpans_minHeightLargerThanGridRows_shouldInitializeSpansToAtMostTheGridRows() { + LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); + info.minWidth = 20; + info.minHeight = 50 * (NUM_OF_ROWS + 1); + InvariantDeviceProfile idp = createIDP(); + + info.initSpans(mContext, idp); + + assertThat(info.spanX).isEqualTo(1); + assertThat(info.spanY).isEqualTo(NUM_OF_ROWS); + } + @Test public void initSpans_minResizeWidthUnspecified_shouldInitializeMinSpansToOne() { LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); @@ -153,6 +182,49 @@ public final class LauncherAppWidgetProviderInfoTest { assertThat(info.minSpanY).isEqualTo(3); } + @Test + public void isMinSizeFulfilled_minWidthAndHeightWithinGridSize_shouldReturnTrue() { + LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); + info.minWidth = 80; + info.minHeight = 80; + info.minResizeWidth = 50; + info.minResizeHeight = 50; + InvariantDeviceProfile idp = createIDP(); + + info.initSpans(mContext, idp); + + assertThat(info.isMinSizeFulfilled()).isTrue(); + } + + @Test + public void + isMinSizeFulfilled_minWidthAndMinResizeWidthExceededGridColumns_shouldReturnFalse() { + LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); + info.minWidth = CELL_SIZE * (NUM_OF_COLS + 2); + info.minHeight = 80; + info.minResizeWidth = CELL_SIZE * (NUM_OF_COLS + 1); + info.minResizeHeight = 50; + InvariantDeviceProfile idp = createIDP(); + + info.initSpans(mContext, idp); + + assertThat(info.isMinSizeFulfilled()).isFalse(); + } + + @Test + public void isMinSizeFulfilled_minHeightAndMinResizeHeightExceededGridRows_shouldReturnFalse() { + LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo(); + info.minWidth = 80; + info.minHeight = CELL_SIZE * (NUM_OF_ROWS + 2); + info.minResizeWidth = 50; + info.minResizeHeight = CELL_SIZE * (NUM_OF_ROWS + 1); + InvariantDeviceProfile idp = createIDP(); + + info.initSpans(mContext, idp); + + assertThat(info.isMinSizeFulfilled()).isFalse(); + } + private InvariantDeviceProfile createIDP() { DeviceProfile profile = Mockito.mock(DeviceProfile.class); doAnswer(i -> { @@ -163,6 +235,8 @@ public final class LauncherAppWidgetProviderInfoTest { InvariantDeviceProfile idp = new InvariantDeviceProfile(); idp.supportedProfiles.add(profile); + idp.numColumns = NUM_OF_COLS; + idp.numRows = NUM_OF_ROWS; return idp; } diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java index 14108f614c..5a29171361 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java @@ -32,13 +32,44 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo public static final String CLS_CUSTOM_WIDGET_PREFIX = "#custom-widget-"; + /** + * The desired number of cells that this widget occupies horizontally in + * {@link com.android.launcher3.CellLayout}. + */ public int spanX; + + /** + * The desired number of cells that this widget occupies vertically in + * {@link com.android.launcher3.CellLayout}. + */ public int spanY; + + /** + * The minimum number of cells that this widget can occupy horizontally in + * {@link com.android.launcher3.CellLayout}. + */ public int minSpanX; + + /** + * The minimum number of cells that this widget can occupy vertically in + * {@link com.android.launcher3.CellLayout}. + */ public int minSpanY; + + /** + * The maximum number of cells that this widget can occupy horizontally in + * {@link com.android.launcher3.CellLayout}. + */ public int maxSpanX; + + /** + * The maximum number of cells that this widget can occupy vertically in + * {@link com.android.launcher3.CellLayout}. + */ public int maxSpanY; + private boolean mIsMinSizeFulfilled; + public static LauncherAppWidgetProviderInfo fromProviderInfo(Context context, AppWidgetProviderInfo info) { final LauncherAppWidgetProviderInfo launcherInfo; @@ -133,8 +164,20 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo this.minSpanY = minSpanY; this.maxSpanX = maxSpanX; this.maxSpanY = maxSpanY; - this.spanX = spanX; - this.spanY = spanY; + this.mIsMinSizeFulfilled = Math.min(spanX, minSpanX) <= idp.numColumns + && Math.min(spanY, minSpanY) <= idp.numRows; + // Ensures the default span X and span Y will not exceed the current grid size. + this.spanX = Math.min(spanX, idp.numColumns); + this.spanY = Math.min(spanY, idp.numRows); + } + + /** + * Returns {@code true} if the widget's minimum size requirement can be fulfilled in the device + * grid setting, {@link InvariantDeviceProfile}, that was passed in + * {@link #initSpans(Context, InvariantDeviceProfile)}. + */ + public boolean isMinSizeFulfilled() { + return mIsMinSizeFulfilled; } private int getSpanX(Rect widgetPadding, int widgetWidth, int cellSpacing, float cellWidth) { diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index be18e546d2..51c5b12b6e 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -254,13 +254,11 @@ public class WidgetsModel { } // Ensure that all widgets we show can be added on a workspace of this size - int minSpanX = Math.min(item.widgetInfo.spanX, item.widgetInfo.minSpanX); - int minSpanY = Math.min(item.widgetInfo.spanY, item.widgetInfo.minSpanY); - if (minSpanX > mIdp.numColumns || minSpanY > mIdp.numRows) { + if (!item.widgetInfo.isMinSizeFulfilled()) { if (DEBUG) { Log.d(TAG, String.format( - "Widget %s : (%d X %d) can't fit on this device", - item.componentName, minSpanX, minSpanY)); + "Widget %s : can't fit on this device with a grid size: %dx%d", + item.componentName, mIdp.numColumns, mIdp.numRows)); } return false; }