Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d47d8c7 authored by Steven Ng's avatar Steven Ng
Browse files

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
parent 00628229
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -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;
    }

+45 −2
Original line number Diff line number Diff line
@@ -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) {
+3 −5
Original line number Diff line number Diff line
@@ -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;
                }