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

Commit 999dd2a0 authored by Jordan Silva's avatar Jordan Silva
Browse files

Extract cell size information to responsive grid structure

Bug: 287975993
Flag: ACONFIG com.android.launcher3.enable_responsive_workspace TEAMFOOD
Test: ResponsiveCellSpecsProviderTest
Test: DeviceProfileDumpTest
Test: DeviceProfileResponsiveDumpTest
Change-Id: I26a87d9b690fdfcff1599d862c09e97fe9f9f930
parent 78a2dd66
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -220,6 +220,14 @@
        Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
        <attr name="hotseatSpecsId" format="reference" />
        <attr name="hotseatSpecsTwoPanelId" format="reference" />
        <!-- File that contains the specs for workspace icon and text size.
        Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
        <attr name="workspaceCellSpecsId" format="reference" />
        <attr name="workspaceCellSpecsTwoPanelId" format="reference" />
        <!-- File that contains the specs for all apps icon and text size.
        Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
        <attr name="allAppsCellSpecsId" format="reference" />
        <attr name="allAppsCellSpecsTwoPanelId" format="reference" />

        <!-- By default all categories are enabled -->
        <attr name="deviceCategory" format="integer">
@@ -292,6 +300,11 @@
        <attr name="maxAvailableSize" />
    </declare-styleable>

    <declare-styleable name="CellSpec">
        <attr name="dimensionType" />
        <attr name="maxAvailableSize" />
    </declare-styleable>

    <declare-styleable name="SizeSpec">
        <attr name="fixedSize" format="dimension" />
        <attr name="ofAvailableSpace" format="float" />
+7 −0
Original line number Diff line number Diff line
@@ -228,6 +228,10 @@
    <dimen name="iconSize60dp">66dp</dimen>
    <dimen name="iconSize66dp">72dp</dimen>
    <dimen name="iconSize72dp">79dp</dimen>
    <dimen name="iconSize82dp">90dp</dimen>
    <dimen name="iconSize110dp">121dp</dimen>
    <dimen name="iconSize144dp">158dp</dimen>


    <!--  Icon size steps in dp  -->
    <integer-array name="icon_size_steps">
@@ -240,6 +244,9 @@
        <item>@dimen/iconSize60dp</item>
        <item>@dimen/iconSize66dp</item>
        <item>@dimen/iconSize72dp</item>
        <item>@dimen/iconSize82dp</item>
        <item>@dimen/iconSize110dp</item>
        <item>@dimen/iconSize144dp</item>
    </integer-array>

    <dimen name="minimum_icon_label_size">8sp</dimen>
+89 −50
Original line number Diff line number Diff line
@@ -54,9 +54,11 @@ import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.responsive.CalculatedCellSpec;
import com.android.launcher3.responsive.CalculatedHotseatSpec;
import com.android.launcher3.responsive.CalculatedResponsiveSpec;
import com.android.launcher3.responsive.HotseatSpecsProvider;
import com.android.launcher3.responsive.ResponsiveCellSpecsProvider;
import com.android.launcher3.responsive.ResponsiveSpec.Companion.ResponsiveSpecType;
import com.android.launcher3.responsive.ResponsiveSpec.DimensionType;
import com.android.launcher3.responsive.ResponsiveSpecsProvider;
@@ -125,6 +127,8 @@ public class DeviceProfile {
    private CalculatedResponsiveSpec mResponsiveFolderWidthSpec;
    private CalculatedResponsiveSpec mResponsiveFolderHeightSpec;
    private CalculatedHotseatSpec mResponsiveHotseatSpec;
    private CalculatedCellSpec mResponsiveWorkspaceCellSpec;
    private CalculatedCellSpec mResponsiveAllAppsCellSpec;

    /**
     * The maximum amount of left/right workspace padding as a percentage of the screen width.
@@ -165,7 +169,7 @@ public class DeviceProfile {
    public int iconSizePx;
    public int iconTextSizePx;
    public int iconDrawablePaddingPx;
    private final int mIconDrawablePaddingOriginalPx;
    private int mIconDrawablePaddingOriginalPx;
    public boolean iconCenterVertically;

    public float cellScaleToFit;
@@ -178,7 +182,7 @@ public class DeviceProfile {
    // Folder
    public final int numFolderRows;
    public final int numFolderColumns;
    public float folderLabelTextScale;
    public final float folderLabelTextScale;
    public int folderLabelTextSizePx;
    public int folderFooterHeightPx;
    public int folderIconSizePx;
@@ -330,7 +334,9 @@ public class DeviceProfile {
        mIsResponsiveGrid = inv.workspaceSpecsId != INVALID_RESOURCE_HANDLE
                && inv.allAppsSpecsId != INVALID_RESOURCE_HANDLE
                && inv.folderSpecsId != INVALID_RESOURCE_HANDLE
                && inv.hotseatSpecsId != INVALID_RESOURCE_HANDLE;
                && inv.hotseatSpecsId != INVALID_RESOURCE_HANDLE
                && inv.workspaceCellSpecsId != INVALID_RESOURCE_HANDLE
                && inv.allAppsCellSpecsId != INVALID_RESOURCE_HANDLE;

        mIsScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
        // Determine device posture.
@@ -470,6 +476,7 @@ public class DeviceProfile {
        mWorkspacePageIndicatorOverlapWorkspace =
                res.getDimensionPixelSize(R.dimen.workspace_page_indicator_overlap_workspace);

        if (!mIsResponsiveGrid) {
            TypedArray cellStyle;
            if (inv.cellStyle != INVALID_RESOURCE_HANDLE) {
                cellStyle = context.obtainStyledAttributes(inv.cellStyle,
@@ -481,6 +488,7 @@ public class DeviceProfile {
            mIconDrawablePaddingOriginalPx = cellStyle.getDimensionPixelSize(
                    R.styleable.CellStyle_iconDrawablePadding, 0);
            cellStyle.recycle();
        }

        dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
        dropTargetBarTopMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_top_margin);
@@ -537,6 +545,13 @@ public class DeviceProfile {
            mHotseatBarEdgePaddingPx =
                    isVerticalBarLayout() ? mResponsiveHotseatSpec.getEdgePadding() : 0;
            mHotseatBarWorkspaceSpacePx = 0;

            ResponsiveCellSpecsProvider workspaceCellSpecs = ResponsiveCellSpecsProvider.create(
                    new ResourceHelper(context,
                            isTwoPanels ? inv.workspaceCellSpecsTwoPanelId
                                    : inv.workspaceCellSpecsId));
            mResponsiveWorkspaceCellSpec = workspaceCellSpecs.getCalculatedSpec(
                    responsiveAspectRatio, heightPx);
        } else {
            hotseatQsbSpace = pxFromDp(inv.hotseatQsbSpace[mTypeIndex], mMetrics);
            hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics);
@@ -570,7 +585,13 @@ public class DeviceProfile {

        springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize(
                R.dimen.spring_loaded_hotseat_top_margin);

        if (mIsResponsiveGrid) {
            updateHotseatSizes(mResponsiveWorkspaceCellSpec.getIconSize());
        } else {
            updateHotseatSizes(pxFromDp(inv.iconSize[mTypeIndex], mMetrics));
        }

        if (areNavButtonsInline && !isPhone) {
            inlineNavButtonsEndSpacingPx =
                    res.getDimensionPixelSize(inv.inlineNavButtonsEndSpacing);
@@ -633,6 +654,15 @@ public class DeviceProfile {
                    DimensionType.HEIGHT, numFolderRows,
                    mResponsiveWorkspaceHeightSpec.getAvailableSpace(),
                    mResponsiveWorkspaceHeightSpec);

            ResponsiveCellSpecsProvider allAppsCellSpecs = ResponsiveCellSpecsProvider.create(
                    new ResourceHelper(context,
                            isTwoPanels ? inv.allAppsCellSpecsTwoPanelId
                                    : inv.allAppsCellSpecsId));
            mResponsiveAllAppsCellSpec = allAppsCellSpecs.getCalculatedSpec(
                    responsiveAspectRatio,
                    mResponsiveAllAppsHeightSpec.getAvailableSpace(),
                    mResponsiveWorkspaceCellSpec);
        }

        desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
@@ -969,19 +999,22 @@ public class DeviceProfile {
     * Returns the amount of extra (or unused) vertical space.
     */
    private int updateAvailableDimensions(Resources res) {
        iconCenterVertically = mIsScalableGrid || mIsResponsiveGrid;

        if (mIsResponsiveGrid) {
            updateIconSize(1f, res);
            updateWorkspacePadding();
            return 0;
        }

        float invIconSizeDp = inv.iconSize[mTypeIndex];
        float invIconTextSizeSp = inv.iconTextSize[mTypeIndex];
        iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics));
        iconTextSizePx = pxFromSp(invIconTextSizeSp, mMetrics);
        iconCenterVertically = mIsScalableGrid || mIsResponsiveGrid;

        updateIconSize(1f, res);
        updateWorkspacePadding();

        if (mIsResponsiveGrid) {
            return 0;
        }

        // Check to see if the icons fit within the available height.
        float usedHeight = getCellLayoutHeightSpecification();
        final int maxHeight = getCellLayoutHeight();
@@ -1025,7 +1058,7 @@ public class DeviceProfile {
        // TODO(b/235886078): workaround needed because of this bug
        // Icons are 10% larger on XML than their visual size,
        // so remove that extra space to get labels closer to the correct padding
        int iconVisibleSizePx = (int) Math.round(ICON_VISIBLE_AREA_FACTOR * iconSizePx);
        int iconVisibleSizePx = Math.round(ICON_VISIBLE_AREA_FACTOR * iconSizePx);
        return Math.max(0, iconDrawablePadding - ((iconSizePx - iconVisibleSizePx) / 2));
    }

@@ -1063,6 +1096,10 @@ public class DeviceProfile {
        cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv, scale);

        if (mIsResponsiveGrid) {
            iconSizePx = mResponsiveWorkspaceCellSpec.getIconSize();
            iconTextSizePx = mResponsiveWorkspaceCellSpec.getIconTextSize();
            mIconDrawablePaddingOriginalPx = mResponsiveWorkspaceCellSpec.getIconDrawablePadding();

            cellWidthPx = mResponsiveWorkspaceWidthSpec.getCellSizePx();
            cellHeightPx = mResponsiveWorkspaceHeightSpec.getCellSizePx();

@@ -1168,7 +1205,7 @@ public class DeviceProfile {

        // All apps
        if (mIsResponsiveGrid) {
            updateAllAppsWithResponsiveMeasures(res);
            updateAllAppsWithResponsiveMeasures();
        } else {
            updateAllAppsIconSize(scale, res);
        }
@@ -1267,13 +1304,16 @@ public class DeviceProfile {
        }
    }

    private void updateAllAppsWithResponsiveMeasures(Resources res) {
    private void updateAllAppsWithResponsiveMeasures() {
        allAppsIconSizePx = mResponsiveAllAppsCellSpec.getIconSize();
        allAppsIconTextSizePx = mResponsiveAllAppsCellSpec.getIconTextSize();
        allAppsIconDrawablePaddingPx = getNormalizedIconDrawablePadding(allAppsIconSizePx,
                mResponsiveAllAppsCellSpec.getIconDrawablePadding());
        allAppsBorderSpacePx = new Point(
                mResponsiveAllAppsWidthSpec.getGutterPx(),
                mResponsiveAllAppsHeightSpec.getGutterPx()
        );
        allAppsCellHeightPx = mResponsiveAllAppsHeightSpec.getCellSizePx()
                + mResponsiveAllAppsHeightSpec.getGutterPx();
        allAppsCellHeightPx = mResponsiveAllAppsHeightSpec.getCellSizePx();
        allAppsCellWidthPx = mResponsiveAllAppsWidthSpec.getCellSizePx();

        // This workaround is needed to align AllApps icons with Workspace icons
@@ -1282,22 +1322,6 @@ public class DeviceProfile {
        allAppsPadding.left = mResponsiveAllAppsWidthSpec.getStartPaddingPx() - halfBorder;
        allAppsPadding.right = mResponsiveAllAppsWidthSpec.getEndPaddingPx() - halfBorder;

        // TODO(b/287975993): Remove this after icon size is extracted to responsive grid
        // Copy icon size from the workspace when spec is matchWorkspace or
        // use the default all apps icon size
        if (mResponsiveAllAppsHeightSpec.isCellSizeMatchWorkspace()
                || mResponsiveAllAppsWidthSpec.isCellSizeMatchWorkspace()) {
            allAppsIconSizePx = iconSizePx;
            allAppsIconTextSizePx = iconTextSizePx;
            allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
        } else {
            allAppsIconSizePx = pxFromDp(inv.allAppsIconSize[mTypeIndex], mMetrics);
            allAppsIconTextSizePx = pxFromSp(inv.allAppsIconTextSize[mTypeIndex], mMetrics);
            allAppsIconDrawablePaddingPx = res.getDimensionPixelSize(
                    R.dimen.all_apps_icon_drawable_padding);
            allAppsIconDrawablePaddingPx = getNormalizedIconDrawablePadding(allAppsIconSizePx,
                    allAppsIconDrawablePaddingPx);
        }

        // Reduce the size of the app icon if it doesn't fit
        if (allAppsCellWidthPx < allAppsIconSizePx) {
@@ -1322,6 +1346,8 @@ public class DeviceProfile {
            allAppsIconDrawablePaddingPx = cellContentDimensions.getIconDrawablePaddingPx();
            allAppsIconTextSizePx = cellContentDimensions.getIconTextSizePx();
        }

        allAppsCellHeightPx += mResponsiveAllAppsHeightSpec.getGutterPx();
    }

    /**
@@ -1390,15 +1416,14 @@ public class DeviceProfile {
    }

    private void updateFolderCellSize(float scale, Resources res) {
        float invIconSizeDp = inv.iconSize[mTypeIndex];
        folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
        folderChildTextSizePx = pxFromSp(inv.iconTextSize[mTypeIndex], mMetrics, scale);
        folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics, scale),
        int minLabelTextSize = pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics, scale);
        if (mIsResponsiveGrid) {
            folderChildIconSizePx = mResponsiveWorkspaceCellSpec.getIconSize();
            folderChildTextSizePx = mResponsiveWorkspaceCellSpec.getIconTextSize();
            folderLabelTextSizePx = Math.max(minLabelTextSize,
                    (int) (folderChildTextSizePx * folderLabelTextScale));

            int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);

        if (mIsResponsiveGrid) {
            folderCellWidthPx = mResponsiveFolderWidthSpec.getCellSizePx();
            folderCellHeightPx = mResponsiveFolderHeightSpec.getCellSizePx();
            folderContentPaddingTop = mResponsiveFolderHeightSpec.getStartPaddingPx();
@@ -1425,9 +1450,20 @@ public class DeviceProfile {
            folderChildIconSizePx = cellContentDimensions.getIconSizePx();
            folderChildDrawablePaddingPx = cellContentDimensions.getIconDrawablePaddingPx();
            folderChildTextSizePx = cellContentDimensions.getIconTextSizePx();
            folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics, scale),
            folderLabelTextSizePx = Math.max(minLabelTextSize,
                    (int) (folderChildTextSizePx * folderLabelTextScale));
        } else if (mIsScalableGrid) {
            return;
        }

        float invIconSizeDp = inv.iconSize[mTypeIndex];
        float invIconTextSizeDp = inv.iconTextSize[mTypeIndex];
        folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
        folderChildTextSizePx = pxFromSp(invIconTextSizeDp, mMetrics, scale);
        folderLabelTextSizePx = Math.max(minLabelTextSize,
                (int) (folderChildTextSizePx * folderLabelTextScale));
        int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);

        if (mIsScalableGrid) {
            if (inv.folderStyle == INVALID_RESOURCE_HANDLE) {
                folderCellWidthPx = roundPxValueFromFloat(getCellSize().x * scale);
                folderCellHeightPx = roundPxValueFromFloat(getCellSize().y * scale);
@@ -2136,6 +2172,9 @@ public class DeviceProfile {
            writer.println(prefix + "\tmResponsiveFolderHeightSpec:" + mResponsiveFolderHeightSpec);
            writer.println(prefix + "\tmResponsiveFolderWidthSpec:" + mResponsiveFolderWidthSpec);
            writer.println(prefix + "\tmResponsiveHotseatSpec:" + mResponsiveHotseatSpec);
            writer.println(prefix + "\tmResponsiveWorkspaceCellSpec:"
                    + mResponsiveWorkspaceCellSpec);
            writer.println(prefix + "\tmResponsiveAllAppsCellSpec:" + mResponsiveAllAppsCellSpec);
        }
    }

+34 −0
Original line number Diff line number Diff line
@@ -191,8 +191,18 @@ public class InvariantDeviceProfile {
    public int folderSpecsId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int folderSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int hotseatSpecsId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int hotseatSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int workspaceCellSpecsId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int workspaceCellSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int allAppsCellSpecsId = INVALID_RESOURCE_HANDLE;
    @XmlRes
    public int allAppsCellSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;

    public String dbFile;
    public int defaultLayoutId;
@@ -375,6 +385,10 @@ public class InvariantDeviceProfile {
        folderSpecsTwoPanelId = closestProfile.mFolderSpecsTwoPanelId;
        hotseatSpecsId = closestProfile.mHotseatSpecsId;
        hotseatSpecsTwoPanelId = closestProfile.mHotseatSpecsTwoPanelId;
        workspaceCellSpecsId = closestProfile.mWorkspaceCellSpecsId;
        workspaceCellSpecsTwoPanelId = closestProfile.mWorkspaceCellSpecsTwoPanelId;
        allAppsCellSpecsId = closestProfile.mAllAppsCellSpecsId;
        allAppsCellSpecsTwoPanelId = closestProfile.mAllAppsCellSpecsTwoPanelId;
        this.deviceType = deviceType;

        inlineNavButtonsEndSpacing = closestProfile.inlineNavButtonsEndSpacing;
@@ -827,6 +841,10 @@ public class InvariantDeviceProfile {
        private final int mFolderSpecsTwoPanelId;
        private final int mHotseatSpecsId;
        private final int mHotseatSpecsTwoPanelId;
        private final int mWorkspaceCellSpecsId;
        private final int mWorkspaceCellSpecsTwoPanelId;
        private final int mAllAppsCellSpecsId;
        private final int mAllAppsCellSpecsTwoPanelId;

        public GridOption(Context context, AttributeSet attrs) {
            TypedArray a = context.obtainStyledAttributes(
@@ -909,6 +927,18 @@ public class InvariantDeviceProfile {
                mHotseatSpecsTwoPanelId = a.getResourceId(
                        R.styleable.GridDisplayOption_hotseatSpecsTwoPanelId,
                        INVALID_RESOURCE_HANDLE);
                mWorkspaceCellSpecsId = a.getResourceId(
                        R.styleable.GridDisplayOption_workspaceCellSpecsId,
                        INVALID_RESOURCE_HANDLE);
                mWorkspaceCellSpecsTwoPanelId = a.getResourceId(
                        R.styleable.GridDisplayOption_workspaceCellSpecsTwoPanelId,
                        INVALID_RESOURCE_HANDLE);
                mAllAppsCellSpecsId = a.getResourceId(
                        R.styleable.GridDisplayOption_allAppsCellSpecsId,
                        INVALID_RESOURCE_HANDLE);
                mAllAppsCellSpecsTwoPanelId = a.getResourceId(
                        R.styleable.GridDisplayOption_allAppsCellSpecsTwoPanelId,
                        INVALID_RESOURCE_HANDLE);
            } else {
                mWorkspaceSpecsId = INVALID_RESOURCE_HANDLE;
                mWorkspaceSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
@@ -918,6 +948,10 @@ public class InvariantDeviceProfile {
                mFolderSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
                mHotseatSpecsId = INVALID_RESOURCE_HANDLE;
                mHotseatSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
                mWorkspaceCellSpecsId = INVALID_RESOURCE_HANDLE;
                mWorkspaceCellSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
                mAllAppsCellSpecsId = INVALID_RESOURCE_HANDLE;
                mAllAppsCellSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
            }

            int inlineForRotation = a.getInt(R.styleable.GridDisplayOption_inlineQsb,
+7 −1
Original line number Diff line number Diff line
@@ -23,7 +23,13 @@ import com.android.launcher3.responsive.ResponsiveSpec.Companion.ResponsiveSpecT
import com.android.launcher3.responsive.ResponsiveSpec.DimensionType
import com.android.launcher3.util.ResourceHelper

class HotseatSpecsProvider(private val groupOfSpecs: List<ResponsiveSpecGroup<HotseatSpec>>) {
class HotseatSpecsProvider(groupOfSpecs: List<ResponsiveSpecGroup<HotseatSpec>>) {

    private val groupOfSpecs: List<ResponsiveSpecGroup<HotseatSpec>>
    init {
        this.groupOfSpecs = groupOfSpecs.sortedBy { it.aspectRatio }
    }

    fun getSpecsByAspectRatio(aspectRatio: Float): ResponsiveSpecGroup<HotseatSpec> {
        check(aspectRatio > 0f) { "Invalid aspect ratio! The value should be bigger than 0." }

Loading