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

Commit 7945649c authored by Thales Lima's avatar Thales Lima
Browse files

Implement calculations of Responsive Grid in DeviceProfile

When a grid has a responsive spec and the feature flag is on, use the new calculations for the sizes in Workspace. This shouldn't affect Scalable grids.

Fix: 277064708
Test: HomeScreenImageTest
Test: DeviceProfileDumpTest
Test: ResponsiveHomeScreenImageTest
Test: DeviceProfileResponsiveDumpTest
Flag: ENABLE_RESPONSIVE_WORKSPACE
Change-Id: Idef3d17fbfa1b2e0c82c12e7784a7584f1ba1b88
parent 5644e3f1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
            setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
            setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
            defaultIconSize = grid.iconSizePx;
            setCenterVertically(grid.isScalableGrid);
            setCenterVertically(grid.iconCenterVertically);
        } else if (mDisplay == DISPLAY_ALL_APPS) {
            setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
            setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx);
+85 −51
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ public class DeviceProfile {

    public final float aspectRatio;

    public final boolean isScalableGrid;
    private final boolean mIsScalableGrid;
    private final int mTypeIndex;

    // Responsive grid
@@ -152,13 +152,14 @@ public class DeviceProfile {
    public int iconTextSizePx;
    public int iconDrawablePaddingPx;
    public int iconDrawablePaddingOriginalPx;
    public boolean iconCenterVertically;

    public float cellScaleToFit;
    public int cellWidthPx;
    public int cellHeightPx;
    public int workspaceCellPaddingXPx;

    public int cellYPaddingPx;
    public int cellYPaddingPx = -1;

    // Folder
    public float folderLabelTextScale;
@@ -305,7 +306,7 @@ public class DeviceProfile {
        // TODO(b/241386436): shouldn't change any launcher behaviour
        mIsResponsiveGrid = inv.workspaceSpecsId != INVALID_RESOURCE_HANDLE;

        isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
        mIsScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
        // Determine device posture.
        mInfo = info;
        isTablet = info.isTablet(windowBounds);
@@ -342,14 +343,6 @@ public class DeviceProfile {
            }
        }

        if (mIsResponsiveGrid) {
            mWorkspaceSpecs = new WorkspaceSpecs(new ResourceHelper(context, inv.workspaceSpecsId));
            mResponsiveWidthSpec = mWorkspaceSpecs.getCalculatedWidthSpec(inv.numColumns,
                    availableWidthPx);
            mResponsiveHeightSpec = mWorkspaceSpecs.getCalculatedHeightSpec(inv.numRows,
                    availableHeightPx);
        }

        if (DisplayController.isTransientTaskbar(context)) {
            float invTransientIconSizeDp = inv.transientTaskbarIconSize[mTypeIndex];
            taskbarIconSize = pxFromDp(invTransientIconSizeDp, mMetrics);
@@ -372,8 +365,6 @@ public class DeviceProfile {
        edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
        workspaceContentScale = res.getFloat(R.dimen.workspace_content_scale);

        desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
        desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
        gridVisualizationPaddingX = res.getDimensionPixelSize(
                R.dimen.grid_visualization_horizontal_cell_spacing);
        gridVisualizationPaddingY = res.getDimensionPixelSize(
@@ -406,7 +397,7 @@ public class DeviceProfile {

        folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);

        if (isScalableGrid && inv.folderStyle != INVALID_RESOURCE_HANDLE) {
        if (mIsScalableGrid && inv.folderStyle != INVALID_RESOURCE_HANDLE) {
            TypedArray folderStyle = context.obtainStyledAttributes(inv.folderStyle,
                    R.styleable.FolderStyle);
            // These are re-set in #updateFolderCellSize if the grid is not scalable
@@ -428,8 +419,6 @@ public class DeviceProfile {
            folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_top_padding_default);
        }

        cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv);
        cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx);
        allAppsBorderSpacePx = new Point(
                pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].x, mMetrics),
                pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].y, mMetrics));
@@ -479,7 +468,7 @@ public class DeviceProfile {
                || inv.inlineQsb[INDEX_TWO_PANEL_LANDSCAPE]
                : inv.inlineQsb[INDEX_DEFAULT] || inv.inlineQsb[INDEX_LANDSCAPE])
                && hotseatQsbHeight > 0;
        isQsbInline = isScalableGrid && inv.inlineQsb[mTypeIndex] && canQsbInline;
        isQsbInline = mIsScalableGrid && inv.inlineQsb[mTypeIndex] && canQsbInline;

        areNavButtonsInline = isTaskbarPresent && !isGestureMode;
        numShownHotseatIcons =
@@ -534,6 +523,21 @@ public class DeviceProfile {
            hotseatBarEndOffset = 0;
        }

        // Needs to be calculated after hotseatBarSizePx is correct,
        // for the available height to be correct
        if (mIsResponsiveGrid) {
            mWorkspaceSpecs = new WorkspaceSpecs(new ResourceHelper(context, inv.workspaceSpecsId));
            mResponsiveWidthSpec = mWorkspaceSpecs.getCalculatedWidthSpec(inv.numColumns,
                    availableWidthPx);
            mResponsiveHeightSpec = mWorkspaceSpecs.getCalculatedHeightSpec(inv.numRows,
                    // don't use availableHeightPx because it subtracts bottom padding,
                    // but the hotseat go behind it
                    heightPx - mInsets.top - hotseatBarSizePx);
        }

        desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
        desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;

        overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin);
        overviewTaskIconSizePx = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
        overviewTaskIconDrawableSizePx =
@@ -554,21 +558,7 @@ public class DeviceProfile {
        // Calculate all of the remaining variables.
        extraSpace = updateAvailableDimensions(res);

        // Now that we have all of the variables calculated, we can tune certain sizes.
        if (isScalableGrid && inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
            // Paddings were created assuming no scaling, so we first unscale the extra space.
            int unscaledExtraSpace = (int) (extraSpace / cellScaleToFit);
            DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
            DevicePadding padding = devicePaddings.getDevicePadding(unscaledExtraSpace);
            maxEmptySpace = padding.getMaxEmptySpacePx();

            int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace);
            int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace);
            int paddingHotseatBottom = padding.getHotseatBottomPadding(unscaledExtraSpace);

            workspaceTopPadding = Math.round(paddingWorkspaceTop * cellScaleToFit);
            workspaceBottomPadding = Math.round(paddingWorkspaceBottom * cellScaleToFit);
        }
        calculateAndSetWorkspaceVerticalPadding(context, inv, extraSpace);

        int cellLayoutPadding =
                isTwoPanels ? cellLayoutBorderSpacePx.x / 2 : res.getDimensionPixelSize(
@@ -649,15 +639,40 @@ public class DeviceProfile {
    }

    private int getHorizontalMarginPx(InvariantDeviceProfile idp, Resources res) {
        if (mIsResponsiveGrid) {
            return mResponsiveWidthSpec.getStartPaddingPx();
        }

        if (isVerticalBarLayout()) {
            return 0;
        }

        return isScalableGrid
        return mIsScalableGrid
                ? pxFromDp(idp.horizontalMargin[mTypeIndex], mMetrics)
                : res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin);
    }

    private void calculateAndSetWorkspaceVerticalPadding(Context context,
            InvariantDeviceProfile inv,
            int extraSpace) {
        if (mIsResponsiveGrid) {
            workspaceTopPadding = mResponsiveHeightSpec.getStartPaddingPx();
            workspaceBottomPadding = mResponsiveHeightSpec.getEndPaddingPx();
        } else if (mIsScalableGrid && inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
            // Paddings were created assuming no scaling, so we first unscale the extra space.
            int unscaledExtraSpace = (int) (extraSpace / cellScaleToFit);
            DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
            DevicePadding padding = devicePaddings.getDevicePadding(unscaledExtraSpace);
            maxEmptySpace = padding.getMaxEmptySpacePx();

            int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace);
            int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace);

            workspaceTopPadding = Math.round(paddingWorkspaceTop * cellScaleToFit);
            workspaceBottomPadding = Math.round(paddingWorkspaceBottom * cellScaleToFit);
        }
    }

    /** Updates hotseatCellHeightPx and hotseatBarSizePx */
    private void updateHotseatSizes(int hotseatIconSizePx) {
        // Ensure there is enough space for folder icons, which have a slightly larger radius.
@@ -682,7 +697,7 @@ public class DeviceProfile {
     * necessary.
     */
    public void recalculateHotseatWidthAndBorderSpace() {
        if (!isScalableGrid) return;
        if (!mIsScalableGrid) return;

        int columns = inv.hotseatColumnSpan[mTypeIndex];
        float hotseatWidthPx = getIconToIconWidthForColumns(columns);
@@ -735,12 +750,16 @@ public class DeviceProfile {
    }

    private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp, float scale) {
        if (!isScalableGrid) {
            return new Point(0, 0);
        }
        int horizontalSpacePx = 0;
        int verticalSpacePx = 0;

        int horizontalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].x, mMetrics, scale);
        int verticalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].y, mMetrics, scale);
        if (mIsResponsiveGrid) {
            horizontalSpacePx = mResponsiveWidthSpec.getGutterPx();
            verticalSpacePx = mResponsiveHeightSpec.getGutterPx();
        } else if (mIsScalableGrid) {
            horizontalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].x, mMetrics, scale);
            verticalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].y, mMetrics, scale);
        }

        return new Point(horizontalSpacePx, verticalSpacePx);
    }
@@ -861,6 +880,7 @@ public class DeviceProfile {
        float invIconTextSizeSp = inv.iconTextSize[mTypeIndex];
        iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics));
        iconTextSizePx = pxFromSp(invIconTextSizeSp, mMetrics);
        iconCenterVertically = mIsScalableGrid || mIsResponsiveGrid;

        updateIconSize(1f, res);

@@ -874,7 +894,7 @@ public class DeviceProfile {
        boolean shouldScale = scaleY < 1f;

        float scaleX = 1f;
        if (isScalableGrid) {
        if (mIsScalableGrid) {
            // We scale to fit the cellWidth and cellHeight in the available space.
            // The benefit of scalable grids is that we can get consistent aspect ratios between
            // devices.
@@ -919,8 +939,18 @@ public class DeviceProfile {
        final boolean isVerticalLayout = isVerticalBarLayout();
        iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * iconScale);
        cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv, scale);
        int cellTextAndPaddingHeight =
                iconDrawablePaddingPx + Utilities.calculateTextHeight(iconTextSizePx);

        if (mIsResponsiveGrid) {
            int cellContentHeight = iconSizePx + cellTextAndPaddingHeight;

            cellWidthPx = mResponsiveWidthSpec.getCellSizePx();
            cellHeightPx = mResponsiveHeightSpec.getCellSizePx();
            cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;

        if (isScalableGrid) {
            // TODO(b/283929701): decrease icon size if content doesn't fit on cell
        } else if (mIsScalableGrid) {
            cellWidthPx = pxFromDp(inv.minCellSize[mTypeIndex].x, mMetrics, scale);
            cellHeightPx = pxFromDp(inv.minCellSize[mTypeIndex].y, mMetrics, scale);

@@ -942,8 +972,6 @@ public class DeviceProfile {
                }
            }

            int cellTextAndPaddingHeight =
                    iconDrawablePaddingPx + Utilities.calculateTextHeight(iconTextSizePx);
            int cellContentHeight = iconSizePx + cellTextAndPaddingHeight;
            if (cellHeightPx < cellContentHeight) {
                // If cellHeight no longer fit iconSize, reduce borderSpace to make cellHeight
@@ -1041,7 +1069,7 @@ public class DeviceProfile {
                + allAppsBorderSpacePx.y;
        // but width is just the cell,
        // the border is added in #updateAllAppsContainerWidth
        if (isScalableGrid) {
        if (mIsScalableGrid) {
            allAppsIconSizePx = pxFromDp(inv.allAppsIconSize[mTypeIndex], mMetrics);
            allAppsIconTextSizePx = pxFromSp(inv.allAppsIconTextSize[mTypeIndex], mMetrics);
            allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
@@ -1124,7 +1152,7 @@ public class DeviceProfile {

        int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);

        if (isScalableGrid) {
        if (mIsScalableGrid) {
            if (inv.folderStyle == INVALID_RESOURCE_HANDLE) {
                folderCellWidthPx = roundPxValueFromFloat(getCellSize().x * scale);
                folderCellHeightPx = roundPxValueFromFloat(getCellSize().y * scale);
@@ -1299,10 +1327,12 @@ public class DeviceProfile {
        } else {
            // Pad the bottom of the workspace with hotseat bar
            // and leave a bit of space in case a widget go all the way down
            int paddingBottom = hotseatBarSizePx + workspaceBottomPadding
                    + workspacePageIndicatorHeight - mWorkspacePageIndicatorOverlapWorkspace
                    - mInsets.bottom;
            int paddingTop = workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx);
            int paddingBottom = hotseatBarSizePx + workspaceBottomPadding - mInsets.bottom;
            if (!mIsResponsiveGrid) {
                paddingBottom +=
                        workspacePageIndicatorHeight - mWorkspacePageIndicatorOverlapWorkspace;
            }
            int paddingTop = workspaceTopPadding + (mIsScalableGrid ? 0 : edgeMarginPx);
            int paddingSide = desiredWorkspaceHorizontalMarginPx;

            padding.set(paddingSide, paddingTop, paddingSide, paddingBottom);
@@ -1378,7 +1408,7 @@ public class DeviceProfile {
                hotseatBarPadding.right = endSpacing;
            }

        } else if (isScalableGrid) {
        } else if (mIsScalableGrid) {
            int sideSpacing = (availableWidthPx - hotseatQsbWidth) / 2;
            hotseatBarPadding.set(sideSpacing,
                    0,
@@ -1598,7 +1628,7 @@ public class DeviceProfile {
        writer.println(prefix + "\taspectRatio:" + aspectRatio);

        writer.println(prefix + "\tisResponsiveGrid:" + mIsResponsiveGrid);
        writer.println(prefix + "\tisScalableGrid:" + isScalableGrid);
        writer.println(prefix + "\tisScalableGrid:" + mIsScalableGrid);

        writer.println(prefix + "\tinv.numRows: " + inv.numRows);
        writer.println(prefix + "\tinv.numColumns: " + inv.numColumns);
@@ -1752,6 +1782,10 @@ public class DeviceProfile {
                getWorkspaceSpringLoadScale(context)));
        writer.println(prefix + pxToDpStr("getCellLayoutHeight()", getCellLayoutHeight()));
        writer.println(prefix + pxToDpStr("getCellLayoutWidth()", getCellLayoutWidth()));
        if (mIsResponsiveGrid) {
            writer.println(prefix + "\tmResponsiveHeightSpec:" + mResponsiveHeightSpec.toString());
            writer.println(prefix + "\tmResponsiveWidthSpec:" + mResponsiveWidthSpec.toString());
        }
    }

    /** Returns a reduced representation of this DeviceProfile. */
+4 −3
Original line number Diff line number Diff line
@@ -154,7 +154,8 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
                    mBorderSpace);
            // Center the icon/folder
            int cHeight = getCellContentHeight();
            int cellPaddingY = dp.isScalableGrid && mContainerType == WORKSPACE
            int cellPaddingY =
                    dp.cellYPaddingPx >= 0 && mContainerType == WORKSPACE
                            ? dp.cellYPaddingPx
                            : (int) Math.max(0, ((lp.height - cHeight) / 2f));

+7 −0
Original line number Diff line number Diff line
@@ -231,6 +231,13 @@ class CalculatedWorkspaceSpec(
        if (workspaceSpec.cellSize.ofRemainderSpace > 0)
            cellSizePx = (workspaceSpec.cellSize.ofRemainderSpace * remainderSpace).roundToInt()
    }

    override fun toString(): String {
        return "CalculatedWorkspaceSpec(availableSpace=$availableSpace, " +
            "cells=$cells, startPaddingPx=$startPaddingPx, endPaddingPx=$endPaddingPx, " +
            "gutterPx=$gutterPx, cellSizePx=$cellSizePx, " +
            "workspaceSpec.maxAvailableSize=${workspaceSpec.maxAvailableSize})"
    }
}

data class WorkspaceSpec(