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

Commit 2636a5d5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add launcher grid spec for tablet" into sc-v2-dev am: b1ae1ca1 am: 287d976c

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/16371727

Change-Id: I609dbebde278dfb335a5a66c6bd71fcfa62a3102
parents 283d6508 287d976c
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -154,7 +154,15 @@
        <attr name="demoModeLayoutId" format="reference" />
        <attr name="isScalable" format="boolean" />
        <attr name="devicePaddingId" format="reference" />
        <attr name="gridEnabled" format="boolean" />
        <!-- By default all categories are enabled -->
        <attr name="deviceCategory" format="integer" >
            <!-- Enable on phone only -->
            <flag name="phone" value="1" />
            <!-- Enable on tablets only -->
            <flag name="tablet" value="2" />
            <!-- Enable on multi display devices only -->
            <flag name="multi_display" value="4" />
        </attr>

    </declare-styleable>

+76 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">

    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
    <!-- Mail Calendar Gallery Store Internet Camera -->
    <resolve
        launcher:container="-101"
        launcher:screen="0"
        launcher:x="0"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
        <favorite launcher:uri="mailto:" />
    </resolve>

    <resolve
        launcher:container="-101"
        launcher:screen="1"
        launcher:x="1"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CALENDAR;end" />
    </resolve>

    <resolve
        launcher:container="-101"
        launcher:screen="2"
        launcher:x="2"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
        <favorite launcher:uri="#Intent;type=images/*;end" />
    </resolve>

    <resolve
        launcher:container="-101"
        launcher:screen="3"
        launcher:x="3"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
        <favorite launcher:uri="market://details?id=com.android.launcher" />
    </resolve>

    <resolve
        launcher:container="-101"
        launcher:screen="4"
        launcher:x="4"
        launcher:y="0" >
        <favorite
            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
        <favorite launcher:uri="http://www.example.com/" />
    </resolve>

    <!-- Resolve camera intent if GoogleCamera is not available e.g. on emulator -->
    <resolve
        launcher:container="-101"
        launcher:screen="5"
        launcher:x="5"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
    </resolve>

</favorites>
+28 −0
Original line number Diff line number Diff line
@@ -133,4 +133,32 @@

    </grid-option>

    <grid-option
        launcher:name="6_by_5"
        launcher:numRows="5"
        launcher:numColumns="6"
        launcher:numFolderRows="3"
        launcher:numFolderColumns="3"
        launcher:numHotseatIcons="6"
        launcher:numAllAppsColumns="6"
        launcher:dbFile="launcher_6_by_5.db"
        launcher:defaultLayoutId="@xml/default_workspace_6x5"
        launcher:deviceCategory="tablet">

        <display-option
            launcher:name="Tablet"
            launcher:minWidthDps="900"
            launcher:minHeightDps="820"
            launcher:minCellHeightDps="104"
            launcher:minCellWidthDps="80"
            launcher:iconImageSize="60"
            launcher:iconTextSize="14"
            launcher:borderSpaceDps="16"
            launcher:allAppsIconSize="60"
            launcher:allAppsIconTextSize="14"
            launcher:allAppsCellSpacingDps="16"
            launcher:canBeDefault="true" />

    </grid-option>

</profiles>
 No newline at end of file

res/xml/device_profiles_split.xml

deleted100644 → 0
+0 −137
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2021 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" >

    <grid-option
        launcher:name="3_by_3"
        launcher:numRows="3"
        launcher:numColumns="3"
        launcher:numFolderRows="2"
        launcher:numFolderColumns="3"
        launcher:numHotseatIcons="3"
        launcher:dbFile="launcher_3_by_3.db"
        launcher:defaultLayoutId="@xml/default_workspace_3x3" >

        <display-option
            launcher:name="Super Short Stubby"
            launcher:minWidthDps="255"
            launcher:minHeightDps="300"
            launcher:iconImageSize="48"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Shorter Stubby"
            launcher:minWidthDps="255"
            launcher:minHeightDps="400"
            launcher:iconImageSize="48"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

    </grid-option>

    <grid-option
        launcher:name="4_by_4"
        launcher:numRows="4"
        launcher:numColumns="4"
        launcher:numFolderRows="3"
        launcher:numFolderColumns="4"
        launcher:numHotseatIcons="4"
        launcher:dbFile="launcher_4_by_4.db"
        launcher:defaultLayoutId="@xml/default_workspace_4x4" >

        <display-option
            launcher:name="Short Stubby"
            launcher:minWidthDps="275"
            launcher:minHeightDps="420"
            launcher:iconImageSize="48"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Stubby"
            launcher:minWidthDps="255"
            launcher:minHeightDps="450"
            launcher:iconImageSize="48"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Nexus S"
            launcher:minWidthDps="296"
            launcher:minHeightDps="491.33"
            launcher:iconImageSize="48"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Nexus 4"
            launcher:minWidthDps="359"
            launcher:minHeightDps="567"
            launcher:iconImageSize="54"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Nexus 5"
            launcher:minWidthDps="335"
            launcher:minHeightDps="567"
            launcher:iconImageSize="54"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

    </grid-option>

    <grid-option
        launcher:name="5_by_5"
        launcher:numRows="5"
        launcher:numColumns="5"
        launcher:numFolderRows="4"
        launcher:numFolderColumns="4"
        launcher:numHotseatIcons="5"
        launcher:numExtendedHotseatIcons="8"
        launcher:dbFile="launcher.db"
        launcher:defaultLayoutId="@xml/default_workspace_5x5" >

        <display-option
            launcher:name="Large Phone"
            launcher:minWidthDps="406"
            launcher:minHeightDps="694"
            launcher:iconImageSize="56"
            launcher:iconTextSize="14.4"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Large Phone Split Display"
            launcher:minWidthDps="406"
            launcher:minHeightDps="694"
            launcher:iconImageSize="56"
            launcher:iconTextSize="14.4"
            launcher:canBeDefault="true" />

        <display-option
            launcher:name="Shorter Stubby"
            launcher:minWidthDps="255"
            launcher:minHeightDps="400"
            launcher:iconImageSize="48"
            launcher:iconTextSize="13.0"
            launcher:canBeDefault="true" />

    </grid-option>

</profiles>
 No newline at end of file
+71 −38
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.util.TypedValue;
import android.util.Xml;
import android.view.Display;

import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

@@ -58,6 +59,8 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -70,6 +73,13 @@ public class InvariantDeviceProfile {
    public static final MainThreadInitializedObject<InvariantDeviceProfile> INSTANCE =
            new MainThreadInitializedObject<>(InvariantDeviceProfile::new);

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({TYPE_PHONE, TYPE_MULTI_DISPLAY, TYPE_TABLET})
    public @interface DeviceType{}
    public static final int TYPE_PHONE = 0;
    public static final int TYPE_MULTI_DISPLAY = 1;
    public static final int TYPE_TABLET = 2;

    private static final String KEY_IDP_GRID_NAME = "idp_grid_name";

    private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
@@ -106,7 +116,7 @@ public class InvariantDeviceProfile {
    public float[] iconTextSize;
    public int iconBitmapSize;
    public int fillResIconDpi;
    public boolean isSplitDisplay;
    public @DeviceType int deviceType;

    public PointF[] minCellSize;

@@ -198,13 +208,21 @@ public class InvariantDeviceProfile {
        String gridName = getCurrentGridName(context);

        // Get the display info based on default display and interpolate it to existing display
        Info defaultInfo = DisplayController.INSTANCE.get(context).getInfo();
        @DeviceType int defaultDeviceType = getDeviceType(defaultInfo);
        DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
                DisplayController.INSTANCE.get(context).getInfo(),
                getPredefinedDeviceProfiles(context, gridName, false, false), false);
                defaultInfo,
                getPredefinedDeviceProfiles(context, gridName, defaultDeviceType,
                        /*allowDisabledGrid=*/false),
                defaultDeviceType);

        Info myInfo = new Info(context, display);
        @DeviceType int deviceType = getDeviceType(myInfo);
        DisplayOption myDisplayOption = invDistWeightedInterpolate(
                myInfo, getPredefinedDeviceProfiles(context, gridName, false, false), false);
                myInfo,
                getPredefinedDeviceProfiles(context, gridName, deviceType,
                        /*allowDisabledGrid=*/false),
                deviceType);

        DisplayOption result = new DisplayOption(defaultDisplayOption.grid)
                .add(myDisplayOption);
@@ -220,7 +238,7 @@ public class InvariantDeviceProfile {
        System.arraycopy(defaultDisplayOption.borderSpaces, 0, result.borderSpaces, 0,
                COUNT_SIZES);

        initGrid(context, myInfo, result, false);
        initGrid(context, myInfo, result, deviceType);
    }

    /**
@@ -246,6 +264,18 @@ public class InvariantDeviceProfile {
        }
    }

    private static @DeviceType int getDeviceType(Info displayInfo) {
        // Each screen has two profiles (portrait/landscape), so devices with four or more
        // supported profiles implies two or more internal displays.
        if (displayInfo.supportedBounds.size() >= 4 && ENABLE_TWO_PANEL_HOME.get()) {
            return TYPE_MULTI_DISPLAY;
        } else if (displayInfo.supportedBounds.stream().allMatch(displayInfo::isTablet)) {
            return TYPE_TABLET;
        } else {
            return TYPE_PHONE;
        }
    }

    public static String getCurrentGridName(Context context) {
        return Utilities.isGridOptionsEnabled(context)
                ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null;
@@ -253,23 +283,19 @@ public class InvariantDeviceProfile {

    private String initGrid(Context context, String gridName) {
        Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
        // Each screen has two profiles (portrait/landscape), so devices with four or more
        // supported profiles implies two or more internal displays.
        boolean isSplitDisplay =
                displayInfo.supportedBounds.size() >= 4 && ENABLE_TWO_PANEL_HOME.get();
        @DeviceType int deviceType = getDeviceType(displayInfo);

        ArrayList<DisplayOption> allOptions =
                getPredefinedDeviceProfiles(context, gridName, isSplitDisplay,
                getPredefinedDeviceProfiles(context, gridName, deviceType,
                        RestoreDbTask.isPending(context));
        DisplayOption displayOption =
                invDistWeightedInterpolate(displayInfo, allOptions, isSplitDisplay);
        initGrid(context, displayInfo, displayOption, isSplitDisplay);
                invDistWeightedInterpolate(displayInfo, allOptions, deviceType);
        initGrid(context, displayInfo, displayOption, deviceType);
        return displayOption.grid.name;
    }

    private void initGrid(
            Context context, Info displayInfo, DisplayOption displayOption,
            boolean isSplitDisplay) {
    private void initGrid(Context context, Info displayInfo, DisplayOption displayOption,
            @DeviceType int deviceType) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        GridOption closestProfile = displayOption.grid;
        numRows = closestProfile.numRows;
@@ -281,7 +307,7 @@ public class InvariantDeviceProfile {
        numFolderColumns = closestProfile.numFolderColumns;
        isScalable = closestProfile.isScalable;
        devicePaddingId = closestProfile.devicePaddingId;
        this.isSplitDisplay = isSplitDisplay;
        this.deviceType = deviceType;

        mExtraAttrs = closestProfile.extraAttrs;

@@ -303,11 +329,11 @@ public class InvariantDeviceProfile {
        horizontalMargin = displayOption.horizontalMargin;

        numShownHotseatIcons = closestProfile.numHotseatIcons;
        numDatabaseHotseatIcons = isSplitDisplay
        numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
                ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;

        numAllAppsColumns = closestProfile.numAllAppsColumns;
        numDatabaseAllAppsColumns = isSplitDisplay
        numDatabaseAllAppsColumns = deviceType == TYPE_MULTI_DISPLAY
                ? closestProfile.numDatabaseAllAppsColumns : closestProfile.numAllAppsColumns;

        if (!Utilities.isGridOptionsEnabled(context)) {
@@ -327,7 +353,7 @@ public class InvariantDeviceProfile {
        defaultWallpaperSize = new Point(displayInfo.currentSize);
        for (WindowBounds bounds : displayInfo.supportedBounds) {
            localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
                    .setUseTwoPanels(isSplitDisplay)
                    .setUseTwoPanels(deviceType == TYPE_MULTI_DISPLAY)
                    .setWindowBounds(bounds).build());

            // Wallpaper size should be the maximum of the all possible sizes Launcher expects
@@ -350,11 +376,6 @@ public class InvariantDeviceProfile {
        defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null);
    }

    @Nullable
    public TypedValue getAttrValue(int attr) {
        return mExtraAttrs == null ? null : mExtraAttrs.get(attr);
    }

    public void addOnChangeListener(OnIDPChangeListener listener) {
        mChangeListeners.add(listener);
    }
@@ -389,12 +410,11 @@ public class InvariantDeviceProfile {
        }
    }

    private static ArrayList<DisplayOption> getPredefinedDeviceProfiles(
            Context context, String gridName, boolean isSplitDisplay, boolean allowDisabledGrid) {
    private static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context,
            String gridName, @DeviceType int deviceType, boolean allowDisabledGrid) {
        ArrayList<DisplayOption> profiles = new ArrayList<>();
        int xmlResource = isSplitDisplay ? R.xml.device_profiles_split : R.xml.device_profiles;

        try (XmlResourceParser parser = context.getResources().getXml(xmlResource)) {
        try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
            final int depth = parser.getDepth();
            int type;
            while (((type = parser.next()) != XmlPullParser.END_TAG ||
@@ -402,8 +422,8 @@ public class InvariantDeviceProfile {
                if ((type == XmlPullParser.START_TAG)
                        && GridOption.TAG_NAME.equals(parser.getName())) {

                    GridOption gridOption =
                            new GridOption(context, Xml.asAttributeSet(parser), isSplitDisplay);
                    GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser),
                            deviceType);
                    if (gridOption.isEnabled || allowDisabledGrid) {
                        final int displayDepth = parser.getDepth();
                        while (((type = parser.next()) != XmlPullParser.END_TAG
@@ -450,9 +470,8 @@ public class InvariantDeviceProfile {
     */
    public List<GridOption> parseAllGridOptions(Context context) {
        List<GridOption> result = new ArrayList<>();
        int xmlResource = isSplitDisplay ? R.xml.device_profiles_split : R.xml.device_profiles;

        try (XmlResourceParser parser = context.getResources().getXml(xmlResource)) {
        try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
            final int depth = parser.getDepth();
            int type;
            while (((type = parser.next()) != XmlPullParser.END_TAG
@@ -460,7 +479,7 @@ public class InvariantDeviceProfile {
                if ((type == XmlPullParser.START_TAG)
                        && GridOption.TAG_NAME.equals(parser.getName())) {
                    GridOption option =
                            new GridOption(context, Xml.asAttributeSet(parser), isSplitDisplay);
                            new GridOption(context, Xml.asAttributeSet(parser), deviceType);
                    if (option.isEnabled) {
                        result.add(option);
                    }
@@ -514,12 +533,12 @@ public class InvariantDeviceProfile {
    }

    private static DisplayOption invDistWeightedInterpolate(
            Info displayInfo, ArrayList<DisplayOption> points, boolean isSplitDisplay) {
            Info displayInfo, ArrayList<DisplayOption> points, @DeviceType int deviceType) {
        int minWidthPx = Integer.MAX_VALUE;
        int minHeightPx = Integer.MAX_VALUE;
        for (WindowBounds bounds : displayInfo.supportedBounds) {
            boolean isTablet = displayInfo.isTablet(bounds);
            if (isTablet && isSplitDisplay) {
            if (isTablet && deviceType == TYPE_MULTI_DISPLAY) {
                // For split displays, take half width per page
                minWidthPx = Math.min(minWidthPx, bounds.availableSize.x / 2);
                minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
@@ -643,6 +662,12 @@ public class InvariantDeviceProfile {

        public static final String TAG_NAME = "grid-option";

        private static final int DEVICE_CATEGORY_PHONE = 1 << 0;
        private static final int DEVICE_CATEGORY_TABLET = 1 << 1;
        private static final int DEVICE_CATEGORY_MULTI_DISPLAY = 1 << 2;
        private static final int DEVICE_CATEGORY_ALL =
                DEVICE_CATEGORY_PHONE | DEVICE_CATEGORY_TABLET | DEVICE_CATEGORY_MULTI_DISPLAY;

        public final String name;
        public final int numRows;
        public final int numColumns;
@@ -666,7 +691,7 @@ public class InvariantDeviceProfile {

        private final SparseArray<TypedValue> extraAttrs;

        public GridOption(Context context, AttributeSet attrs, boolean isSplitDisplay) {
        public GridOption(Context context, AttributeSet attrs, @DeviceType int deviceType) {
            TypedArray a = context.obtainStyledAttributes(
                    attrs, R.styleable.GridDisplayOption);
            name = a.getString(R.styleable.GridDisplayOption_name);
@@ -674,7 +699,7 @@ public class InvariantDeviceProfile {
            numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);

            dbFile = a.getString(R.styleable.GridDisplayOption_dbFile);
            defaultLayoutId = a.getResourceId(isSplitDisplay && a.hasValue(
            defaultLayoutId = a.getResourceId(deviceType == TYPE_MULTI_DISPLAY && a.hasValue(
                    R.styleable.GridDisplayOption_defaultSplitDisplayLayoutId)
                    ? R.styleable.GridDisplayOption_defaultSplitDisplayLayoutId
                    : R.styleable.GridDisplayOption_defaultLayoutId, 0);
@@ -701,7 +726,15 @@ public class InvariantDeviceProfile {
            devicePaddingId = a.getResourceId(
                    R.styleable.GridDisplayOption_devicePaddingId, 0);

            isEnabled = a.getBoolean(R.styleable.GridDisplayOption_gridEnabled, true);
            int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
                    DEVICE_CATEGORY_ALL);
            isEnabled = (deviceType == TYPE_PHONE
                        && ((deviceCategory & DEVICE_CATEGORY_PHONE) == DEVICE_CATEGORY_PHONE))
                    || (deviceType == TYPE_TABLET
                        && ((deviceCategory & DEVICE_CATEGORY_TABLET) == DEVICE_CATEGORY_TABLET))
                    || (deviceType == TYPE_MULTI_DISPLAY
                        && ((deviceCategory & DEVICE_CATEGORY_MULTI_DISPLAY)
                            == DEVICE_CATEGORY_MULTI_DISPLAY));

            a.recycle();
            extraAttrs = Themes.createValueMap(context, attrs,
Loading