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

Commit 64359898 authored by Jonathan Miranda's avatar Jonathan Miranda Committed by android-build-merger
Browse files

Merge "Have consistent All Apps UI between grid size changes." into ub-launcher3-qt-future-dev

am: c3a688a9

Change-Id: I6c9d825e85f55bd3160ab5e2a37e707f3f525459
parents 7242db1a c3a688a9
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -115,8 +115,6 @@
        <attr name="numFolderColumns" format="integer" />
        <!-- numHotseatIcons defaults to numColumns, if not specified -->
        <attr name="numHotseatIcons" format="integer" />
        <!-- numAllAppsColumns defaults to numColumns, if not specified -->
        <attr name="numAllAppsColumns" format="integer" />
        <attr name="defaultLayoutId" format="reference" />
        <attr name="demoModeLayoutId" format="reference" />
    </declare-styleable>
@@ -132,12 +130,6 @@
        <attr name="iconTextSize" format="float" />
        <!-- If true, this display option is used to determine the default grid -->
        <attr name="canBeDefault" format="boolean" />

        <!-- The following values are only enabled if grid is supported. -->
        <!-- allAppsIconSize defaults to iconSize, if not specified -->
        <attr name="allAppsIconSize" format="float" />
        <!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
        <attr name="allAppsIconTextSize" format="float" />
    </declare-styleable>

    <declare-styleable name="CellLayout">
+27 −17
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Surface;

import androidx.annotation.Nullable;

import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.DotRenderer;
@@ -34,6 +36,8 @@ import com.android.launcher3.util.DefaultDisplay;
public class DeviceProfile {

    public final InvariantDeviceProfile inv;
    // IDP with no grid override values.
    @Nullable private final InvariantDeviceProfile originalIdp;

    // Device properties
    public final boolean isTablet;
@@ -134,10 +138,11 @@ public class DeviceProfile {
    public DotRenderer mDotRendererAllApps;

    public DeviceProfile(Context context, InvariantDeviceProfile inv,
            Point minSize, Point maxSize,
            InvariantDeviceProfile originalIDP, Point minSize, Point maxSize,
            int width, int height, boolean isLandscape, boolean isMultiWindowMode) {

        this.inv = inv;
        this.originalIdp = inv;
        this.isLandscape = isLandscape;
        this.isMultiWindowMode = isMultiWindowMode;

@@ -229,6 +234,19 @@ public class DeviceProfile {
            // Recalculate the available dimensions using the new hotseat size.
            updateAvailableDimensions(dm, res);
        }

        if (originalIDP != null) {
            // Grid size change should not affect All Apps UI, so we use the original profile
            // measurements here.
            DeviceProfile originalProfile = isLandscape
                    ? originalIDP.landscapeProfile
                    : originalIDP.portraitProfile;
            allAppsIconSizePx = originalProfile.iconSizePx;
            allAppsIconTextSizePx = originalProfile.iconTextSizePx;
            allAppsCellHeightPx = originalProfile.allAppsCellHeightPx;
            allAppsIconDrawablePaddingPx = originalProfile.iconDrawablePaddingOriginalPx;
            allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;
        }
        updateWorkspacePadding();

        // This is done last, after iconSizePx is calculated above.
@@ -241,8 +259,8 @@ public class DeviceProfile {

    public DeviceProfile copy(Context context) {
        Point size = new Point(availableWidthPx, availableHeightPx);
        return new DeviceProfile(context, inv, size, size, widthPx, heightPx, isLandscape,
                isMultiWindowMode);
        return new DeviceProfile(context, inv, originalIdp, size, size, widthPx, heightPx,
                isLandscape, isMultiWindowMode);
    }

    public DeviceProfile getMultiWindowProfile(Context context, Point mwSize) {
@@ -253,8 +271,8 @@ public class DeviceProfile {
        // In multi-window mode, we can have widthPx = availableWidthPx
        // and heightPx = availableHeightPx because Launcher uses the InvariantDeviceProfiles'
        // widthPx and heightPx values where it's needed.
        DeviceProfile profile = new DeviceProfile(context, inv, mwSize, mwSize, mwSize.x, mwSize.y,
                isLandscape, true);
        DeviceProfile profile = new DeviceProfile(context, inv, originalIdp, mwSize, mwSize,
                mwSize.x, mwSize.y, isLandscape, true);

        // If there isn't enough vertical cell padding with the labels displayed, hide the labels.
        float workspaceCellPaddingY = profile.getCellSize().y - profile.iconSizePx
@@ -338,18 +356,10 @@ public class DeviceProfile {
        }
        cellWidthPx = iconSizePx + iconDrawablePaddingPx;

        // All apps
        if (allAppsHasDifferentNumColumns()) {
            allAppsIconSizePx = ResourceUtils.pxFromDp(inv.allAppsIconSize, dm);
            allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, dm);
            allAppsCellHeightPx = getCellSize(inv.numAllAppsColumns, inv.numAllAppsColumns).y;
            allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
        } else {
        allAppsIconSizePx = iconSizePx;
        allAppsIconTextSizePx = iconTextSizePx;
        allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
        allAppsCellHeightPx = getCellSize().y;
        }
        allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;

        if (isVerticalBarLayout()) {
+96 −72
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class InvariantDeviceProfile {

@@ -191,65 +192,76 @@ public class InvariantDeviceProfile {
        Point smallestSize = new Point(displayInfo.smallestSize);
        Point largestSize = new Point(displayInfo.largestSize);

        ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
        // This guarantees that width < height
        float minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y),
                displayInfo.metrics);
        float minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y),
                displayInfo.metrics);
        // Sort the profiles based on the closeness to the device size
        Collections.sort(allOptions, (a, b) ->
                Float.compare(dist(minWidthDps, minHeightDps, a.minWidthDps, a.minHeightDps),
                        dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps)));
        DisplayOption interpolatedDisplayOption =
                invDistWeightedInterpolate(minWidthDps,  minHeightDps, allOptions);

        GridOption closestProfile = allOptions.get(0).grid;
        numRows = closestProfile.numRows;
        numColumns = closestProfile.numColumns;
        numHotseatIcons = closestProfile.numHotseatIcons;
        defaultLayoutId = closestProfile.defaultLayoutId;
        demoModeLayoutId = closestProfile.demoModeLayoutId;
        numFolderRows = closestProfile.numFolderRows;
        numFolderColumns = closestProfile.numFolderColumns;
        numAllAppsColumns = closestProfile.numAllAppsColumns;
        Point realSize = new Point(displayInfo.realSize);
        // The real size never changes. smallSide and largeSide will remain the
        // same in any orientation.
        int smallSide = Math.min(realSize.x, realSize.y);
        int largeSide = Math.max(realSize.x, realSize.y);

        mExtraAttrs = closestProfile.extraAttrs;
        // We want a list of all options as well as the list of filtered options. This allows us
        // to have a consistent UI for areas that the grid size change should not affect
        // ie. All Apps should be consistent between grid sizes.
        ArrayList<DisplayOption> allOptions = new ArrayList<>();
        ArrayList<DisplayOption> filteredOptions = new ArrayList<>();
        getPredefinedDeviceProfiles(context, gridName, filteredOptions, allOptions);

        if (!closestProfile.name.equals(gridName)) {
            Utilities.getPrefs(context).edit()
                    .putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
        if (allOptions.isEmpty() && filteredOptions.isEmpty()) {
            throw new RuntimeException("No display option with canBeDefault=true");
        }

        iconSize = interpolatedDisplayOption.iconSize;
        iconShapePath = getIconShapePath(context);
        landscapeIconSize = interpolatedDisplayOption.landscapeIconSize;
        iconBitmapSize = ResourceUtils.pxFromDp(iconSize, displayInfo.metrics);
        iconTextSize = interpolatedDisplayOption.iconTextSize;
        fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
        // Sort the profiles based on the closeness to the device size
        Comparator<DisplayOption> comparator = (a, b) -> Float.compare(dist(minWidthDps,
                minHeightDps, a.minWidthDps, a.minHeightDps),
                dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps));

        if (Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)) {
            allAppsIconSize = interpolatedDisplayOption.allAppsIconSize;
            allAppsIconTextSize = interpolatedDisplayOption.allAppsIconTextSize;
        // Calculate the device profiles as if there is no grid override.
        Collections.sort(allOptions, comparator);
        DisplayOption interpolatedDisplayOption =
                invDistWeightedInterpolate(minWidthDps,  minHeightDps, allOptions);
        initGridOption(context, allOptions, interpolatedDisplayOption, displayInfo.metrics);

        // Create IDP with no grid override values.
        InvariantDeviceProfile originalIDP = new InvariantDeviceProfile(this);
        originalIDP.landscapeProfile = new DeviceProfile(context, this, null, smallestSize,
                largestSize, largeSide, smallSide, true /* isLandscape */,
                false /* isMultiWindowMode */);
        originalIDP.portraitProfile = new DeviceProfile(context, this, null, smallestSize,
                largestSize, smallSide, largeSide, false /* isLandscape */,
                false /* isMultiWindowMode */);

        if (filteredOptions.isEmpty()) {
            filteredOptions = allOptions;

            landscapeProfile = originalIDP.landscapeProfile;
            portraitProfile = originalIDP.portraitProfile;
        } else {
            allAppsIconSize = iconSize;
            allAppsIconTextSize = iconTextSize;
        }
            Collections.sort(filteredOptions, comparator);
            interpolatedDisplayOption =
                    invDistWeightedInterpolate(minWidthDps, minHeightDps, filteredOptions);

        // If the partner customization apk contains any grid overrides, apply them
        // Supported overrides: numRows, numColumns, iconSize
        applyPartnerDeviceProfileOverrides(context, displayInfo.metrics);
            initGridOption(context, filteredOptions, interpolatedDisplayOption,
                    displayInfo.metrics);
            numAllAppsColumns = originalIDP.numAllAppsColumns;

        Point realSize = new Point(displayInfo.realSize);
        // The real size never changes. smallSide and largeSide will remain the
        // same in any orientation.
        int smallSide = Math.min(realSize.x, realSize.y);
        int largeSide = Math.max(realSize.x, realSize.y);
            landscapeProfile = new DeviceProfile(context, this, originalIDP, smallestSize,
                    largestSize, largeSide, smallSide, true /* isLandscape */,
                    false /* isMultiWindowMode */);
            portraitProfile = new DeviceProfile(context, this, originalIDP, smallestSize,
                    largestSize, smallSide, largeSide, false /* isLandscape */,
                    false /* isMultiWindowMode */);
        }

        landscapeProfile = new DeviceProfile(context, this, smallestSize, largestSize,
                largeSide, smallSide, true /* isLandscape */, false /* isMultiWindowMode */);
        portraitProfile = new DeviceProfile(context, this, smallestSize, largestSize,
                smallSide, largeSide, false /* isLandscape */, false /* isMultiWindowMode */);
        GridOption closestProfile = filteredOptions.get(0).grid;
        if (!closestProfile.name.equals(gridName)) {
            Utilities.getPrefs(context).edit()
                    .putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
        }

        // We need to ensure that there is enough extra space in the wallpaper
        // for the intended parallax effects
@@ -267,6 +279,33 @@ public class InvariantDeviceProfile {
        return closestProfile.name;
    }

    private void initGridOption(Context context, ArrayList<DisplayOption> options,
            DisplayOption displayOption, DisplayMetrics metrics) {
        GridOption closestProfile = options.get(0).grid;
        numRows = closestProfile.numRows;
        numColumns = closestProfile.numColumns;
        numHotseatIcons = closestProfile.numHotseatIcons;
        defaultLayoutId = closestProfile.defaultLayoutId;
        demoModeLayoutId = closestProfile.demoModeLayoutId;
        numFolderRows = closestProfile.numFolderRows;
        numFolderColumns = closestProfile.numFolderColumns;
        numAllAppsColumns = numColumns;

        mExtraAttrs = closestProfile.extraAttrs;

        iconSize = displayOption.iconSize;
        iconShapePath = getIconShapePath(context);
        landscapeIconSize = displayOption.landscapeIconSize;
        iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
        iconTextSize = displayOption.iconTextSize;
        fillResIconDpi = getLauncherIconDensity(iconBitmapSize);

        // If the partner customization apk contains any grid overrides, apply them
        // Supported overrides: numRows, numColumns, iconSize
        applyPartnerDeviceProfileOverrides(context, metrics);
    }


    @Nullable
    public TypedValue getAttrValue(int attr) {
        return mExtraAttrs == null ? null : mExtraAttrs.get(attr);
@@ -344,7 +383,13 @@ public class InvariantDeviceProfile {
        }
    }

    static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
    /**
     * @param gridName The current grid name.
     * @param filteredOptionsOut List filled with all the filtered options based on gridName.
     * @param allOptionsOut List filled with all the options that can be the default option.
     */
    static void getPredefinedDeviceProfiles(Context context, String gridName,
            ArrayList<DisplayOption> filteredOptionsOut, ArrayList<DisplayOption> allOptionsOut) {
        ArrayList<DisplayOption> profiles = new ArrayList<>();
        try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
            final int depth = parser.getDepth();
@@ -371,26 +416,19 @@ public class InvariantDeviceProfile {
            throw new RuntimeException(e);
        }

        ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
        if (!TextUtils.isEmpty(gridName)) {
            for (DisplayOption option : profiles) {
                if (gridName.equals(option.grid.name)) {
                    filteredProfiles.add(option);
                    filteredOptionsOut.add(option);
                }
            }
        }
        if (filteredProfiles.isEmpty()) {
            // No grid found, use the default options

        for (DisplayOption option : profiles) {
            if (option.canBeDefault) {
                    filteredProfiles.add(option);
                }
                allOptionsOut.add(option);
            }
        }
        if (filteredProfiles.isEmpty()) {
            throw new RuntimeException("No display option with canBeDefault=true");
        }
        return filteredProfiles;
    }

    private int getLauncherIconDensity(int requiredSize) {
@@ -514,8 +552,6 @@ public class InvariantDeviceProfile {

        private final int numHotseatIcons;

        private final int numAllAppsColumns;

        private final int defaultLayoutId;
        private final int demoModeLayoutId;

@@ -538,8 +574,6 @@ public class InvariantDeviceProfile {
                    R.styleable.GridDisplayOption_numFolderRows, numRows);
            numFolderColumns = a.getInt(
                    R.styleable.GridDisplayOption_numFolderColumns, numColumns);
            numAllAppsColumns = a.getInt(
                    R.styleable.GridDisplayOption_numAllAppsColumns, numColumns);

            a.recycle();

@@ -559,8 +593,6 @@ public class InvariantDeviceProfile {
        private float iconSize;
        private float iconTextSize;
        private float landscapeIconSize;
        private float allAppsIconSize;
        private float allAppsIconTextSize;

        DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
            this.grid = grid;
@@ -579,10 +611,6 @@ public class InvariantDeviceProfile {
                    iconSize);
            iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);

            allAppsIconSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconSize,
                    iconSize);
            allAppsIconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconTextSize,
                    iconTextSize);
            a.recycle();
        }

@@ -597,18 +625,14 @@ public class InvariantDeviceProfile {
        private DisplayOption multiply(float w) {
            iconSize *= w;
            landscapeIconSize *= w;
            allAppsIconSize *= w;
            iconTextSize *= w;
            allAppsIconTextSize *= w;
            return this;
        }

        private DisplayOption add(DisplayOption p) {
            iconSize += p.iconSize;
            landscapeIconSize += p.landscapeIconSize;
            allAppsIconSize += p.allAppsIconSize;
            iconTextSize += p.iconTextSize;
            allAppsIconTextSize += p.allAppsIconTextSize;
            return this;
        }
    }