Merge "Calculate hotseat width based on available width" into tm-qpr-dev am: c92b40f10a

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

Change-Id: I87e1a5b68b8fc8ebf30e8ba9839f87367eb9f6d1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Thales Lima
2022-08-08 09:24:09 +00:00
committed by Automerger Merge Worker
13 changed files with 448 additions and 279 deletions
+1 -1
View File
@@ -77,7 +77,7 @@
<!-- Taskbar 3 button spacing -->
<dimen name="taskbar_button_margin_5_5">94.5dp</dimen>
<dimen name="taskbar_button_margin_6_5">94.5dp</dimen>
<dimen name="taskbar_button_margin_6_5">219.6dp</dimen>
<dimen name="taskbar_button_margin_4_5">84dp</dimen>
<dimen name="taskbar_button_margin_4_4">79dp</dimen>
</resources>
+1 -1
View File
@@ -278,7 +278,7 @@
<!-- Taskbar 3 button spacing -->
<dimen name="taskbar_button_space_inbetween">24dp</dimen>
<dimen name="taskbar_button_margin_5_5">26dp</dimen>
<dimen name="taskbar_button_margin_6_5">26dp</dimen>
<dimen name="taskbar_button_margin_6_5">75dp</dimen>
<dimen name="taskbar_button_margin_4_5">47dp</dimen>
<dimen name="taskbar_button_margin_4_4">47dp</dimen>
<dimen name="taskbar_button_margin_default">47dp</dimen>
@@ -338,18 +338,18 @@ class DeviceProfileTest : DeviceProfileBaseTest() {
"\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
"\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
"\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
"\thotseatBarEndOffset: 597.0px (298.5dp)\n" +
"\thotseatBarEndOffset: 705.0px (352.5dp)\n" +
"\thotseatQsbSpace: 64.0px (32.0dp)\n" +
"\thotseatQsbHeight: 126.0px (63.0dp)\n" +
"\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
"\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 959.0px (479.5dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 597.0px (298.5dp)\n" +
"\tnumShownHotseatIcons: 5\n" +
"\thotseatBorderSpace: 101.0px (50.5dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 954.0px (477.0dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 705.0px (352.5dp)\n" +
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 36.0px (18.0dp)\n" +
"\tisQsbInline: true\n" +
"\thotseatQsbWidth: 855.0px (427.5dp)\n" +
"\thotseatQsbWidth: 619.0px (309.5dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -578,16 +578,16 @@ class DeviceProfileTest : DeviceProfileBaseTest() {
"\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
"\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
"\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
"\thotseatBarEndOffset: 460.0px (230.0dp)\n" +
"\thotseatBarEndOffset: 558.0px (279.0dp)\n" +
"\thotseatQsbSpace: 64.0px (32.0dp)\n" +
"\thotseatQsbHeight: 126.0px (63.0dp)\n" +
"\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
"\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 76.0px (38.0dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 460.0px (230.0dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 558.0px (279.0dp)\n" +
"\tnumShownHotseatIcons: 5\n" +
"\thotseatBorderSpace: 116.0px (58.0dp)\n" +
"\thotseatBorderSpace: 73.0px (36.5dp)\n" +
"\tisQsbInline: false\n" +
"\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
"\tisTaskbarPresent:true\n" +
@@ -824,10 +824,10 @@ class DeviceProfileTest : DeviceProfileBaseTest() {
"\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
"\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 216.0px (82.28571dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 106.0px (40.38095dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 744.0px (283.42856dp)\n" +
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 61.0px (23.238094dp)\n" +
"\thotseatBorderSpace: 83.0px (31.619047dp)\n" +
"\tisQsbInline: false\n" +
"\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
"\tisTaskbarPresent:true\n" +
@@ -1064,10 +1064,10 @@ class DeviceProfileTest : DeviceProfileBaseTest() {
"\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
"\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 128.0px (48.761906dp)\n" +
"\tgetHotseatLayoutPadding(context).left: 78.0px (29.714285dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 660.0px (251.42857dp)\n" +
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 47.0px (17.904762dp)\n" +
"\thotseatBorderSpace: 57.0px (21.714285dp)\n" +
"\tisQsbInline: false\n" +
"\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
"\tisTaskbarPresent:true\n" +
@@ -0,0 +1,163 @@
/*
* Copyright (C) 2022 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.
*/
package com.android.quickstep
import android.graphics.Rect
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.DeviceProfileBaseTest
import com.android.launcher3.util.WindowBounds
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class HotseatWidthCalculationTest : DeviceProfileBaseTest() {
/**
* This is a case when after setting the hotseat, the space needs to be recalculated
* but it doesn't need to change QSB width or remove icons
*/
@Test
fun distribute_border_space_when_space_is_enough_portrait() {
initializeVarsForTablet(isGestureMode = false)
windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(558)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(69)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(176)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(558)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1445)
}
/**
* This is a case when after setting the hotseat, and recalculating spaces
* it still needs to remove icons for everything to fit
*/
@Test
fun decrease_num_of_icons_when_not_enough_space_portrait() {
initializeVarsForTablet(isGestureMode = false)
windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(558)
assertThat(dp.numShownHotseatIcons).isEqualTo(4)
assertThat(dp.hotseatBorderSpace).isEqualTo(76)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(122)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(558)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1058)
}
/**
* This is a case when after setting the hotseat, the space needs to be recalculated
* but it doesn't need to change QSB width or remove icons
*/
@Test
fun distribute_border_space_when_space_is_enough_landscape() {
initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(744)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(83)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(106)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(744)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1467)
}
/**
* This is a case when the hotseat spans a certain amount of columns
* and the nav buttons push the hotseat to the side, but not enough to change the border space.
*/
@Test
fun nav_buttons_dont_interfere_with_required_hotseat_width() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
inv?.apply {
hotseatColumnSpan = IntArray(4) { 4 }
inlineQsb = BooleanArray(4) { false }
}
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(108)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(631)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1227)
}
/**
* This is a case when after setting the hotseat, the QSB width needs to be changed to fit
*/
@Test
fun decrease_qsb_when_not_enough_space_landscape() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(36)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(884)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
assertThat(dp.isQsbInline).isTrue()
assertThat(dp.hotseatQsbWidth).isEqualTo(559)
}
/**
* This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
* it still needs to remove icons for everything to fit
*/
@Test
fun decrease_num_of_icons_when_not_enough_space_landscape() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
assertThat(dp.numShownHotseatIcons).isEqualTo(5)
assertThat(dp.hotseatBorderSpace).isEqualTo(56)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(801)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
assertThat(dp.isQsbInline).isTrue()
assertThat(dp.hotseatQsbWidth).isEqualTo(480)
}
}
-12
View File
@@ -158,9 +158,6 @@
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
<!-- Number of icons to use when shrinking the hotseat size,
defaults to numHotseatIcons / 2 -->
<attr name="numShrunkenHotseatIcons" format="integer" />
<!-- Number of icons to use when extending the hotseat size,
defaults to 2 * numHotseatIcons -->
<attr name="numExtendedHotseatIcons" format="integer" />
@@ -328,15 +325,6 @@
if not specified -->
<attr name="allAppsBorderSpaceTwoPanelLandscapeVertical" format="float" />
<!-- defaults to borderSpaceDps, if not specified -->
<attr name="hotseatBorderSpace" format="float" />
<!-- defaults to hotseatBorderSpace, if not specified -->
<attr name="hotseatBorderSpaceLandscape" format="float" />
<!-- defaults to hotseatBorderSpace, if not specified -->
<attr name="hotseatBorderSpaceTwoPanelLandscape" format="float" />
<!-- defaults to hotseatBorderSpace, if not specified -->
<attr name="hotseatBorderSpaceTwoPanelPortrait" format="float" />
<!-- defaults to res.hotseat_bar_bottom_space_default, if not specified -->
<attr name="hotseatBarBottomSpace" format="float" />
<!-- defaults to hotseatBarBottomSpace, if not specified -->
+2
View File
@@ -354,6 +354,8 @@
<dimen name="taskbar_stashed_size">0dp</dimen>
<dimen name="qsb_widget_height">0dp</dimen>
<dimen name="qsb_shadow_height">0dp</dimen>
<dimen name="min_hotseat_icon_space">18dp</dimen>
<dimen name="min_hotseat_qsb_width">0dp</dimen>
<dimen name="taskbar_icon_size">44dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
<dimen name="taskbar_icon_spacing">8dp</dimen>
-2
View File
@@ -200,8 +200,6 @@
launcher:allAppsBorderSpaceHorizontal="8"
launcher:allAppsBorderSpaceVertical="16"
launcher:allAppsBorderSpaceLandscape="16"
launcher:hotseatBorderSpace="58"
launcher:hotseatBorderSpaceLandscape="50.4"
launcher:hotseatBarBottomSpace="76"
launcher:hotseatBarBottomSpaceLandscape="40"
launcher:canBeDefault="true" />
+90 -27
View File
@@ -158,7 +158,7 @@ public class DeviceProfile {
public int folderChildDrawablePaddingPx;
// Hotseat
public final int numShownHotseatIcons;
public int numShownHotseatIcons;
public int hotseatCellHeightPx;
public final boolean areNavButtonsInline;
// In portrait: size = height, in landscape: size = width
@@ -362,15 +362,9 @@ public class DeviceProfile {
&& hotseatQsbHeight > 0;
isQsbInline = inv.inlineQsb[mTypeIndex] && canQsbInline;
// We shrink hotseat sizes regardless of orientation, if nav buttons are inline and QSB
// might be inline in either orientations, to keep hotseat size consistent across rotation.
areNavButtonsInline = isTaskbarPresent && !isGestureMode;
if (areNavButtonsInline && canQsbInline) {
numShownHotseatIcons = inv.numShrunkenHotseatIcons;
} else {
numShownHotseatIcons =
isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
}
numShownHotseatIcons =
isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
@@ -460,8 +454,7 @@ public class DeviceProfile {
updateWorkspacePadding();
// Hotseat and QSB width depends on updated cellSize and workspace padding
hotseatBorderSpace = calculateHotseatBorderSpace();
hotseatQsbWidth = calculateQsbWidth();
recalculateHotseatWidthAndBorderSpace(res);
// AllApps height calculation depends on updated cellSize
if (isTablet) {
@@ -499,7 +492,7 @@ public class DeviceProfile {
* QSB width is always calculated because when in 3 button nav the width doesn't follow the
* width of the hotseat.
*/
private int calculateQsbWidth() {
private int calculateQsbWidth(int hotseatBorderSpace) {
if (isQsbInline) {
int columns = getPanelCount() * inv.numColumns;
return getIconToIconWidthForColumns(columns)
@@ -546,6 +539,70 @@ public class DeviceProfile {
}
}
private void recalculateHotseatWidthAndBorderSpace(Resources res) {
hotseatBorderSpace = calculateHotseatBorderSpace();
hotseatQsbWidth = calculateQsbWidth(hotseatBorderSpace);
// Spaces should be correct when there nav buttons are not inline
if (!areNavButtonsInline) {
return;
}
// Get the maximum width that the hotseat can be
int columns = getPanelCount() * inv.numColumns;
int maxHotseatWidth = getIconToIconWidthForColumns(columns);
int sideSpace = (availableWidthPx - maxHotseatWidth) / 2;
int inlineButtonsOverlap = Math.max(0, hotseatBarEndOffset - sideSpace);
// decrease how much the nav buttons go "inside" the hotseat
maxHotseatWidth -= inlineButtonsOverlap;
// Get how much space is required to show the hotseat with QSB
int requiredWidth = getHotseatRequiredWidth();
// If spaces are fine, use them
if (requiredWidth <= maxHotseatWidth) {
return;
}
// Calculate the difference of widths and remove a little from each space between icons
// and QSB if it's inline
int spaceDiff = requiredWidth - maxHotseatWidth;
int numOfSpaces = numShownHotseatIcons - (isQsbInline ? 0 : 1);
hotseatBorderSpace -= (spaceDiff / numOfSpaces);
int minHotseatIconSpaceDp = res.getDimensionPixelSize(R.dimen.min_hotseat_icon_space);
int minHotseatQsbWidthDp = res.getDimensionPixelSize(R.dimen.min_hotseat_qsb_width);
if (hotseatBorderSpace >= minHotseatIconSpaceDp) {
return;
}
// Border space can't be less than the minimum
hotseatBorderSpace = minHotseatIconSpaceDp;
requiredWidth = getHotseatRequiredWidth();
// If there is an inline qsb, change its size
if (isQsbInline) {
hotseatQsbWidth -= requiredWidth - maxHotseatWidth;
if (hotseatQsbWidth >= minHotseatQsbWidthDp) {
return;
}
// QSB can't be less than the minimum
hotseatQsbWidth = minHotseatQsbWidthDp;
}
// If it still doesn't fit, start removing icons
do {
numShownHotseatIcons--;
requiredWidth = getHotseatRequiredWidth();
} while (requiredWidth > maxHotseatWidth && numShownHotseatIcons > 1);
// Add back some space between the icons
spaceDiff = maxHotseatWidth - requiredWidth;
numOfSpaces = numShownHotseatIcons - (isQsbInline ? 0 : 1);
hotseatBorderSpace += (spaceDiff / numOfSpaces);
}
private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
return getCellLayoutBorderSpace(idp, 1f);
}
@@ -778,15 +835,10 @@ public class DeviceProfile {
*/
private int calculateHotseatBorderSpace() {
if (!isScalableGrid) return 0;
//TODO(http://b/228998082) remove this when 3 button spaces are fixed
if (areNavButtonsInline) {
return pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics);
} else {
int columns = inv.hotseatColumnSpan[mTypeIndex];
float hotseatWidthPx = getIconToIconWidthForColumns(columns);
float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
}
int columns = inv.hotseatColumnSpan[mTypeIndex];
float hotseatWidthPx = getIconToIconWidthForColumns(columns);
float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
}
@@ -1078,10 +1130,7 @@ public class DeviceProfile {
hotseatBarSizePx - hotseatBarBottomPadding - hotseatCellHeightPx;
// Push icons to the side
int additionalQsbSpace = isQsbInline ? hotseatQsbWidth + hotseatBorderSpace : 0;
int requiredWidth = iconSizePx * numShownHotseatIcons
+ hotseatBorderSpace * (numShownHotseatIcons - 1)
+ additionalQsbSpace;
int requiredWidth = getHotseatRequiredWidth();
int hotseatWidth = Math.min(requiredWidth, availableWidthPx - hotseatBarEndOffset);
int sideSpacing = (availableWidthPx - hotseatWidth) / 2;
@@ -1090,9 +1139,9 @@ public class DeviceProfile {
boolean isRtl = Utilities.isRtl(context.getResources());
if (isRtl) {
hotseatBarPadding.right += additionalQsbSpace;
hotseatBarPadding.right += getAdditionalQsbSpace();
} else {
hotseatBarPadding.left += additionalQsbSpace;
hotseatBarPadding.left += getAdditionalQsbSpace();
}
if (hotseatBarEndOffset > sideSpacing) {
@@ -1127,6 +1176,20 @@ public class DeviceProfile {
return hotseatBarPadding;
}
private int getAdditionalQsbSpace() {
return isQsbInline ? hotseatQsbWidth + hotseatBorderSpace : 0;
}
/**
* Calculate how much space the hotseat needs to be shown completely
*/
private int getHotseatRequiredWidth() {
int additionalQsbSpace = getAdditionalQsbSpace();
return iconSizePx * numShownHotseatIcons
+ hotseatBorderSpace * (numShownHotseatIcons - 1)
+ additionalQsbSpace;
}
/**
* Returns the number of pixels the QSB is translated from the bottom of the screen.
*/
@@ -128,7 +128,6 @@ public class InvariantDeviceProfile {
public PointF[] borderSpaces;
public float folderBorderSpace;
public float[] hotseatBorderSpaces;
public int inlineNavButtonsEndSpacing;
public float[] horizontalMargin;
@@ -145,11 +144,6 @@ public class InvariantDeviceProfile {
*/
public int numShownHotseatIcons;
/**
* Number of icons inside the hotseat area when using 3 buttons navigation.
*/
public int numShrunkenHotseatIcons;
/**
* Number of icons inside the hotseat area that is stored in the database. This is greater than
* or equal to numnShownHotseatIcons, allowing for a seamless transition between two hotseat
@@ -176,7 +170,7 @@ public class InvariantDeviceProfile {
public String dbFile;
public int defaultLayoutId;
int demoModeLayoutId;
boolean[] inlineQsb = new boolean[COUNT_SIZES];
public boolean[] inlineQsb = new boolean[COUNT_SIZES];
/**
* An immutable list of supported profiles.
@@ -364,11 +358,9 @@ public class InvariantDeviceProfile {
horizontalMargin = displayOption.horizontalMargin;
numShownHotseatIcons = closestProfile.numHotseatIcons;
numShrunkenHotseatIcons = closestProfile.numShrunkenHotseatIcons;
numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
hotseatColumnSpan = closestProfile.hotseatColumnSpan;
hotseatBorderSpaces = displayOption.hotseatBorderSpaces;
hotseatBarBottomSpace = displayOption.hotseatBarBottomSpace;
hotseatQsbSpace = displayOption.hotseatQsbSpace;
@@ -737,7 +729,6 @@ public class InvariantDeviceProfile {
private final int numAllAppsColumns;
private final int numDatabaseAllAppsColumns;
private final int numHotseatIcons;
private final int numShrunkenHotseatIcons;
private final int numDatabaseHotseatIcons;
private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
@@ -777,8 +768,6 @@ public class InvariantDeviceProfile {
numHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
numShrunkenHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numShrunkenHotseatIcons, numHotseatIcons / 2);
numDatabaseHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
@@ -842,8 +831,6 @@ public class InvariantDeviceProfile {
private float folderBorderSpace;
private final PointF[] borderSpaces = new PointF[COUNT_SIZES];
private final float[] horizontalMargin = new float[COUNT_SIZES];
//TODO(http://b/228998082) remove this when 3 button spaces are fixed
private final float[] hotseatBorderSpaces = new float[COUNT_SIZES];
private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES];
private final float[] hotseatQsbSpace = new float[COUNT_SIZES];
@@ -1059,18 +1046,6 @@ public class InvariantDeviceProfile {
R.styleable.ProfileDisplayOption_horizontalMarginTwoPanelPortrait,
horizontalMargin[INDEX_DEFAULT]);
hotseatBorderSpaces[INDEX_DEFAULT] = a.getFloat(
R.styleable.ProfileDisplayOption_hotseatBorderSpace, borderSpace);
hotseatBorderSpaces[INDEX_LANDSCAPE] = a.getFloat(
R.styleable.ProfileDisplayOption_hotseatBorderSpaceLandscape,
hotseatBorderSpaces[INDEX_DEFAULT]);
hotseatBorderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelLandscape,
hotseatBorderSpaces[INDEX_DEFAULT]);
hotseatBorderSpaces[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelPortrait,
hotseatBorderSpaces[INDEX_DEFAULT]);
hotseatBarBottomSpace[INDEX_DEFAULT] = a.getFloat(
R.styleable.ProfileDisplayOption_hotseatBarBottomSpace,
ResourcesCompat.getFloat(context.getResources(),
@@ -1133,7 +1108,6 @@ public class InvariantDeviceProfile {
minCellSize[i].x *= w;
minCellSize[i].y *= w;
horizontalMargin[i] *= w;
hotseatBorderSpaces[i] *= w;
hotseatBarBottomSpace[i] *= w;
hotseatQsbSpace[i] *= w;
allAppsCellSize[i].x *= w;
@@ -1158,7 +1132,6 @@ public class InvariantDeviceProfile {
minCellSize[i].x += p.minCellSize[i].x;
minCellSize[i].y += p.minCellSize[i].y;
horizontalMargin[i] += p.horizontalMargin[i];
hotseatBorderSpaces[i] += p.hotseatBorderSpaces[i];
hotseatBarBottomSpace[i] += p.hotseatBarBottomSpace[i];
hotseatQsbSpace[i] += p.hotseatQsbSpace[i];
allAppsCellSize[i].x += p.allAppsCellSize[i].x;
+13
View File
@@ -24,6 +24,18 @@ filegroup {
"src/**/*.java",
"src/**/*.kt"
],
exclude_srcs: [
":launcher-non-quickstep-tests-src"
],
}
// Source code used for non-quickstep tests
filegroup {
name: "launcher-non-quickstep-tests-src",
srcs: [
"src/com/android/launcher3/nonquickstep/**/*.java",
"src/com/android/launcher3/nonquickstep/**/*.kt",
],
}
// Source code used for oop test helpers
@@ -84,6 +96,7 @@ android_test {
name: "Launcher3Tests",
srcs: [
":launcher-tests-src",
":launcher-non-quickstep-tests-src",
],
static_libs: ["Launcher3TestLib"],
libs: [
@@ -114,7 +114,6 @@ abstract class DeviceProfileBaseTest {
PointF(16f, 16f)
).toTypedArray()
folderBorderSpace = 16f
hotseatBorderSpaces = FloatArray(4) { 16f }
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_5
horizontalMargin = FloatArray(4) { 22f }
@@ -136,8 +135,6 @@ abstract class DeviceProfileBaseTest {
numShownHotseatIcons = 4
numShrunkenHotseatIcons = 4
numDatabaseHotseatIcons = 4
hotseatColumnSpan = IntArray(4) { 4 }
@@ -200,7 +197,6 @@ abstract class DeviceProfileBaseTest {
PointF(16f, 64f),
PointF(16f, 64f)
).toTypedArray()
hotseatBorderSpaces = floatArrayOf(58f, 50.4f, 58f, 58f)
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5
horizontalMargin = floatArrayOf(54f, 120f, 54f, 54f)
@@ -222,8 +218,6 @@ abstract class DeviceProfileBaseTest {
numShownHotseatIcons = 6
numShrunkenHotseatIcons = 5
numDatabaseHotseatIcons = 6
hotseatColumnSpan = intArrayOf(6, 4, 6, 6)
@@ -297,7 +291,6 @@ abstract class DeviceProfileBaseTest {
PointF(20f, 20f)
).toTypedArray()
folderBorderSpace = 16f
hotseatBorderSpaces = floatArrayOf(36f, 36f, 18f, 23.3f)
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_4
horizontalMargin = floatArrayOf(21.5f, 21.5f, 22.5f, 30.5f)
@@ -319,8 +312,6 @@ abstract class DeviceProfileBaseTest {
numShownHotseatIcons = 6
numShrunkenHotseatIcons = 6
numDatabaseHotseatIcons = 6
hotseatColumnSpan = IntArray(4) { 6 }
@@ -1,185 +0,0 @@
/*
* Copyright (C) 2022 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.
*/
package com.android.launcher3
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY
import com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE
import com.android.launcher3.InvariantDeviceProfile.TYPE_TABLET
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
/**
* Test for [DeviceProfile]
*/
@SmallTest
@RunWith(AndroidJUnit4::class)
class HotseatShownIconsTest : DeviceProfileBaseTest() {
@Test
fun hotseat_size_is_shrunk_if_needed_when_large_screen() {
initializeVarsForTablet(isLandscape = true)
inv = inv!!.apply {
deviceType = TYPE_MULTI_DISPLAY
inlineQsb = booleanArrayOf(
false,
false,
false,
true // two panels landscape
)
}
useTwoPanels = true
isGestureMode = false
val dp = newDP()
if (dp.hotseatQsbHeight > 0) {
assertThat(dp.isQsbInline).isTrue()
assertThat(dp.numShownHotseatIcons).isEqualTo(5)
} else { // Launcher3 doesn't have QSB height
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
}
}
/**
* For consistency, the hotseat should shrink if any orientation on the device type has an
* inline qsb
*/
@Test
fun hotseat_size_is_shrunk_even_in_portrait_when_large_screen() {
initializeVarsForTablet()
inv = inv!!.apply {
deviceType = TYPE_MULTI_DISPLAY
inlineQsb = booleanArrayOf(
false,
false,
false,
true // two panels landscape
)
}
useTwoPanels = true
isGestureMode = false
val dp = newDP()
if (dp.hotseatQsbHeight > 0) {
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(5)
} else { // Launcher3 doesn't have QSB height
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
}
}
@Test
fun hotseat_size_is_default_when_small_screen() {
initializeVarsForPhone()
inv = inv!!.apply {
deviceType = TYPE_MULTI_DISPLAY
}
useTwoPanels = true
val dp = newDP()
assertThat(dp.numShownHotseatIcons).isEqualTo(4)
}
@Test
fun hotseat_size_is_not_shrunk_on_gesture_tablet() {
initializeVarsForTablet(isLandscape = true)
inv = inv!!.apply {
deviceType = TYPE_TABLET
inlineQsb = booleanArrayOf(
false,
true, // landscape
false,
false
)
numShownHotseatIcons = 6
}
isGestureMode = true
val dp = newDP()
if (dp.hotseatQsbHeight > 0) {
assertThat(dp.isQsbInline).isTrue()
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
} else { // Launcher3 doesn't have QSB height
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
}
}
@Test
fun hotseat_size_is_shrunk_if_needed_on_tablet() {
initializeVarsForTablet(isLandscape = true)
inv = inv!!.apply {
deviceType = TYPE_TABLET
inlineQsb = booleanArrayOf(
false,
true, // landscape
false,
false
)
numShownHotseatIcons = 6
}
isGestureMode = false
val dp = newDP()
if (dp.hotseatQsbHeight > 0) {
assertThat(dp.isQsbInline).isTrue()
assertThat(dp.numShownHotseatIcons).isEqualTo(5)
} else { // Launcher3 doesn't have QSB height
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
}
}
/**
* For consistency, the hotseat should shrink if any orientation on the device type has an
* inline qsb
*/
@Test
fun hotseat_size_is_shrunk_even_in_portrait_on_tablet() {
initializeVarsForTablet()
inv = inv!!.apply {
deviceType = TYPE_TABLET
inlineQsb = booleanArrayOf(
false,
true, // landscape
false,
false
)
numShownHotseatIcons = 6
}
isGestureMode = false
val dp = newDP()
if (dp.hotseatQsbHeight > 0) {
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(5)
} else { // Launcher3 doesn't have QSB height
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
}
}
}
@@ -0,0 +1,163 @@
/*
* Copyright (C) 2022 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.
*/
package com.android.launcher3.nonquickstep
import android.graphics.Rect
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.DeviceProfileBaseTest
import com.android.launcher3.util.WindowBounds
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class HotseatWidthCalculationTest : DeviceProfileBaseTest() {
/**
* This is a case when after setting the hotseat, the space needs to be recalculated
* but it doesn't need to change QSB width or remove icons
*/
@Test
fun distribute_border_space_when_space_is_enough_portrait() {
initializeVarsForTablet(isGestureMode = false)
windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(145)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1445)
}
/**
* This is a case when after setting the hotseat, and recalculating spaces
* it still needs to remove icons for everything to fit
*/
@Test
fun decrease_num_of_icons_when_not_enough_space_portrait() {
initializeVarsForTablet(isGestureMode = false)
windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(94)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(121)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(121)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1058)
}
/**
* This is a case when after setting the hotseat, the space needs to be recalculated
* but it doesn't need to change QSB width or remove icons
*/
@Test
fun distribute_border_space_when_space_is_enough_landscape() {
initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(105)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(370)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(370)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1467)
}
/**
* This is a case when the hotseat spans a certain amount of columns
* and the nav buttons push the hotseat to the side, but not enough to change the border space.
*/
@Test
fun nav_buttons_dont_interfere_with_required_hotseat_width() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
inv?.apply {
hotseatColumnSpan = IntArray(4) { 4 }
inlineQsb = BooleanArray(4) { false }
}
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(100)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(668)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(668)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1224)
}
/**
* This is a case when after setting the hotseat, the QSB width needs to be changed to fit
*/
@Test
fun decrease_qsb_when_not_enough_space_landscape() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(96)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(643)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(643)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1174)
}
/**
* This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
* it still needs to remove icons for everything to fit
*/
@Test
fun decrease_num_of_icons_when_not_enough_space_landscape() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(89)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(589)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(589)
assertThat(dp.isQsbInline).isFalse()
assertThat(dp.hotseatQsbWidth).isEqualTo(1081)
}
}