summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/values/attrs.xml12
-rw-r--r--src/com/android/launcher3/DeviceProfile.java32
-rw-r--r--src/com/android/launcher3/InvariantDeviceProfile.java26
-rw-r--r--src/com/android/launcher3/util/DisplayController.java8
-rw-r--r--src/com/android/launcher3/util/window/WindowManagerProxy.java1
-rw-r--r--tests/src/com/android/launcher3/DeviceProfileBaseTest.kt133
-rw-r--r--tests/src/com/android/launcher3/DeviceProfileTest.kt219
-rw-r--r--tests/src/com/android/launcher3/HotseatSizeTest.kt186
-rw-r--r--tests/src/com/android/launcher3/InlineQsbTest.kt105
9 files changed, 480 insertions, 242 deletions
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index c96a2284e7..fcb9053418 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -316,6 +316,18 @@
<attr name="horizontalMarginTwoPanelLandscape" format="float"/>
<!-- defaults to horizontalMargin if not specified -->
<attr name="horizontalMarginTwoPanelPortrait" format="float"/>
+
+ <!-- By default all are false -->
+ <attr name="inlineQsb" format="integer" >
+ <!-- Enable on landscape only -->
+ <flag name="portrait" value="1" />
+ <!-- Enable on portrait only -->
+ <flag name="landscape" value="2" />
+ <!-- Enable on two panel portrait only -->
+ <flag name="twoPanelPortrait" value="4" />
+ <!-- Enable on two panel landscape only -->
+ <flag name="twoPanelLandscape" value="8" />
+ </attr>
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 0c33bce5e0..db31350c59 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -16,6 +16,10 @@
package com.android.launcher3;
+import static com.android.launcher3.InvariantDeviceProfile.INDEX_DEFAULT;
+import static com.android.launcher3.InvariantDeviceProfile.INDEX_LANDSCAPE;
+import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_LANDSCAPE;
+import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_PORTRAIT;
import static com.android.launcher3.ResourceUtils.pxFromDp;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
@@ -58,7 +62,6 @@ public class DeviceProfile {
// Device properties
public final boolean isTablet;
- public final boolean isLargeTablet;
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
public final boolean isTwoPanels;
@@ -253,7 +256,6 @@ public class DeviceProfile {
// Determine device posture.
mInfo = info;
isTablet = info.isTablet(windowBounds);
- isLargeTablet = info.isLargeTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && useTwoPanels;
isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
@@ -278,15 +280,15 @@ public class DeviceProfile {
if (isTwoPanels) {
if (isLandscape) {
- mTypeIndex = InvariantDeviceProfile.INDEX_TWO_PANEL_LANDSCAPE;
+ mTypeIndex = INDEX_TWO_PANEL_LANDSCAPE;
} else {
- mTypeIndex = InvariantDeviceProfile.INDEX_TWO_PANEL_PORTRAIT;
+ mTypeIndex = INDEX_TWO_PANEL_PORTRAIT;
}
} else {
if (isLandscape) {
- mTypeIndex = InvariantDeviceProfile.INDEX_LANDSCAPE;
+ mTypeIndex = INDEX_LANDSCAPE;
} else {
- mTypeIndex = InvariantDeviceProfile.INDEX_DEFAULT;
+ mTypeIndex = INDEX_DEFAULT;
}
}
@@ -348,9 +350,12 @@ public class DeviceProfile {
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
- // Whether QSB might be inline in appropriate orientation (landscape).
- boolean canQsbInline = isLargeTablet && hotseatQsbHeight > 0;
- isQsbInline = canQsbInline && isLandscape;
+ // Whether QSB might be inline in appropriate orientation (e.g. landscape).
+ boolean canQsbInline = (isTwoPanels ? inv.inlineQsb[INDEX_TWO_PANEL_PORTRAIT]
+ || inv.inlineQsb[INDEX_TWO_PANEL_LANDSCAPE]
+ : inv.inlineQsb[INDEX_DEFAULT] || inv.inlineQsb[INDEX_LANDSCAPE])
+ && 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.
@@ -388,7 +393,7 @@ public class DeviceProfile {
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size);
hotseatBorderSpace = pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics);
updateHotseatIconSize(
- pxFromDp(inv.iconSize[InvariantDeviceProfile.INDEX_DEFAULT], mMetrics));
+ pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
qsbBottomMarginOriginalPx = isScalableGrid
? res.getDimensionPixelSize(R.dimen.scalable_grid_qsb_bottom_margin)
@@ -812,11 +817,11 @@ public class DeviceProfile {
private void updateFolderCellSize(float scale, Resources res) {
float invIconSizeDp = isVerticalBarLayout()
- ? inv.iconSize[InvariantDeviceProfile.INDEX_LANDSCAPE]
- : inv.iconSize[InvariantDeviceProfile.INDEX_DEFAULT];
+ ? inv.iconSize[INDEX_LANDSCAPE]
+ : inv.iconSize[INDEX_DEFAULT];
folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
folderChildTextSizePx =
- pxFromSp(inv.iconTextSize[InvariantDeviceProfile.INDEX_DEFAULT], mMetrics, scale);
+ pxFromSp(inv.iconTextSize[INDEX_DEFAULT], mMetrics, scale);
folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale);
int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
@@ -1167,7 +1172,6 @@ public class DeviceProfile {
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
writer.println(prefix + "\tisTablet:" + isTablet);
- writer.println(prefix + "\tisLargeTablet:" + isLargeTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"
+ transposeLayoutWithOrientation);
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 219ed9e371..9f367ef766 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -167,6 +167,7 @@ public class InvariantDeviceProfile {
public String dbFile;
public int defaultLayoutId;
int demoModeLayoutId;
+ boolean[] inlineQsb = new boolean[COUNT_SIZES];
/**
* An immutable list of supported profiles.
@@ -250,6 +251,8 @@ public class InvariantDeviceProfile {
COUNT_SIZES);
System.arraycopy(defaultDisplayOption.borderSpaces, 0, result.borderSpaces, 0,
COUNT_SIZES);
+ System.arraycopy(defaultDisplayOption.inlineQsb, 0, result.inlineQsb, 0,
+ COUNT_SIZES);
initGrid(context, myInfo, result, deviceType);
}
@@ -371,6 +374,8 @@ public class InvariantDeviceProfile {
devicePaddings = new DevicePaddings(context, devicePaddingId);
}
+ inlineQsb = displayOption.inlineQsb;
+
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, metrics);
@@ -783,12 +788,18 @@ public class InvariantDeviceProfile {
@VisibleForTesting
static final class DisplayOption {
+ private static final int INLINE_QSB_FOR_PORTRAIT = 1 << 0;
+ private static final int INLINE_QSB_FOR_LANDSCAPE = 1 << 1;
+ private static final int INLINE_QSB_FOR_TWO_PANEL_PORTRAIT = 1 << 2;
+ private static final int INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE = 1 << 3;
+ private static final int DONT_INLINE_QSB = 0;
public final GridOption grid;
private final float minWidthDps;
private final float minHeightDps;
private final boolean canBeDefault;
+ private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
private final PointF[] minCellSize = new PointF[COUNT_SIZES];
@@ -815,6 +826,19 @@ public class InvariantDeviceProfile {
canBeDefault = a.getBoolean(R.styleable.ProfileDisplayOption_canBeDefault, false);
+ int inlineForRotation = a.getInt(R.styleable.ProfileDisplayOption_inlineQsb,
+ DONT_INLINE_QSB);
+ inlineQsb[INDEX_DEFAULT] =
+ (inlineForRotation & INLINE_QSB_FOR_PORTRAIT) == INLINE_QSB_FOR_PORTRAIT;
+ inlineQsb[INDEX_LANDSCAPE] =
+ (inlineForRotation & INLINE_QSB_FOR_LANDSCAPE) == INLINE_QSB_FOR_LANDSCAPE;
+ inlineQsb[INDEX_TWO_PANEL_PORTRAIT] =
+ (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_PORTRAIT)
+ == INLINE_QSB_FOR_TWO_PANEL_PORTRAIT;
+ inlineQsb[INDEX_TWO_PANEL_LANDSCAPE] =
+ (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE)
+ == INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE;
+
float x;
float y;
@@ -1004,6 +1028,7 @@ public class InvariantDeviceProfile {
allAppsIconSizes[i] = 0;
allAppsIconTextSizes[i] = 0;
allAppsBorderSpaces[i] = new PointF();
+ inlineQsb[i] = false;
}
}
@@ -1046,6 +1071,7 @@ public class InvariantDeviceProfile {
allAppsIconTextSizes[i] += p.allAppsIconTextSizes[i];
allAppsBorderSpaces[i].x += p.allAppsBorderSpaces[i].x;
allAppsBorderSpaces[i].y += p.allAppsBorderSpaces[i].y;
+ inlineQsb[i] |= p.inlineQsb[i];
}
folderBorderSpace += p.folderBorderSpace;
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 8b4ff85f90..44a0ef4436 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -26,7 +26,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
-import static com.android.launcher3.util.window.WindowManagerProxy.MIN_LARGE_TABLET_WIDTH;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
@@ -349,13 +348,6 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
}
/**
- * Returns {@code true} if the bounds represent a large tablet.
- */
- public boolean isLargeTablet(WindowBounds bounds) {
- return smallestSizeDp(bounds) >= MIN_LARGE_TABLET_WIDTH;
- }
-
- /**
* Returns smallest size in dp for given bounds.
*/
public float smallestSizeDp(WindowBounds bounds) {
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
index ba3d9814ec..71460f3fbb 100644
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java
@@ -58,7 +58,6 @@ import com.android.launcher3.util.WindowBounds;
public class WindowManagerProxy implements ResourceBasedOverride {
public static final int MIN_TABLET_WIDTH = 600;
- public static final int MIN_LARGE_TABLET_WIDTH = 720;
public static final MainThreadInitializedObject<WindowManagerProxy> INSTANCE =
forOverride(WindowManagerProxy.class, R.string.window_manager_proxy_class);
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
new file mode 100644
index 0000000000..e598df961d
--- /dev/null
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -0,0 +1,133 @@
+/*
+ * 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 android.content.Context
+import android.graphics.PointF
+import androidx.test.core.app.ApplicationProvider
+import com.android.launcher3.util.DisplayController.Info
+import com.android.launcher3.util.WindowBounds
+import org.junit.Before
+import org.mockito.ArgumentMatchers.any
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when` as whenever
+
+abstract class DeviceProfileBaseTest {
+
+ protected var context: Context? = null
+ protected var inv: InvariantDeviceProfile? = null
+ protected var info: Info = mock(Info::class.java)
+ protected var windowBounds: WindowBounds? = null
+ protected var isMultiWindowMode: Boolean = false
+ protected var transposeLayoutWithOrientation: Boolean = false
+ protected var useTwoPanels: Boolean = false
+ protected var isGestureMode: Boolean = true
+
+ @Before
+ fun setUp() {
+ context = ApplicationProvider.getApplicationContext()
+ // make sure to reset values
+ useTwoPanels = false
+ isGestureMode = true
+ }
+
+ protected fun newDP(): DeviceProfile = DeviceProfile(
+ context,
+ inv,
+ info,
+ windowBounds,
+ isMultiWindowMode,
+ transposeLayoutWithOrientation,
+ useTwoPanels,
+ isGestureMode
+ )
+
+ protected fun initializeVarsForPhone(isLandscape: Boolean = false) {
+ val (x, y) = if (isLandscape)
+ Pair(3120, 1440)
+ else
+ Pair(1440, 3120)
+
+ windowBounds = WindowBounds(x, y, x, y - 100, 0)
+
+ whenever(info.isTablet(any())).thenReturn(false)
+
+ inv = newScalableInvariantDeviceProfile()
+ }
+
+ protected fun initializeVarsForTablet(isLandscape: Boolean = false) {
+ val (x, y) = if (isLandscape)
+ Pair(2560, 1600)
+ else
+ Pair(1600, 2560)
+
+ windowBounds = WindowBounds(x, y, x, y - 100, 0)
+
+ whenever(info.isTablet(any())).thenReturn(true)
+
+ inv = newScalableInvariantDeviceProfile()
+ }
+
+ /**
+ * A very generic grid, just to make qsb tests work. For real calculations, make sure to use
+ * values that better represent a real grid.
+ */
+ protected fun newScalableInvariantDeviceProfile(): InvariantDeviceProfile =
+ InvariantDeviceProfile().apply {
+ isScalable = true
+ numColumns = 5
+ numRows = 5
+ numShownHotseatIcons = 5
+ numDatabaseHotseatIcons = 6
+ numShrunkenHotseatIcons = 4
+ horizontalMargin = FloatArray(4) { 22f }
+ borderSpaces = listOf(
+ PointF(16f, 16f),
+ PointF(16f, 16f),
+ PointF(16f, 16f),
+ PointF(16f, 16f)
+ ).toTypedArray()
+ allAppsBorderSpaces = listOf(
+ PointF(16f, 16f),
+ PointF(16f, 16f),
+ PointF(16f, 16f),
+ PointF(16f, 16f)
+ ).toTypedArray()
+ hotseatBorderSpaces = FloatArray(4) { 16f }
+ iconSize = FloatArray(4) { 56f }
+ allAppsIconSize = FloatArray(4) { 56f }
+ iconTextSize = FloatArray(4) { 14f }
+ allAppsIconTextSize = FloatArray(4) { 14f }
+ minCellSize = listOf(
+ PointF(64f, 83f),
+ PointF(64f, 83f),
+ PointF(64f, 83f),
+ PointF(64f, 83f)
+ ).toTypedArray()
+ allAppsCellSize = listOf(
+ PointF(64f, 83f),
+ PointF(64f, 83f),
+ PointF(64f, 83f),
+ PointF(64f, 83f)
+ ).toTypedArray()
+ inlineQsb = booleanArrayOf(
+ false,
+ false,
+ false,
+ false
+ )
+ }
+} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/DeviceProfileTest.kt b/tests/src/com/android/launcher3/DeviceProfileTest.kt
deleted file mode 100644
index d1e91ed072..0000000000
--- a/tests/src/com/android/launcher3/DeviceProfileTest.kt
+++ /dev/null
@@ -1,219 +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 android.content.Context
-import android.graphics.PointF
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.util.DisplayController.Info
-import com.android.launcher3.util.WindowBounds
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.*
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class DeviceProfileTest {
-
- private var context: Context? = null
- private var inv: InvariantDeviceProfile? = null
- private var info: Info = mock(Info::class.java)
- private var windowBounds: WindowBounds? = null
- private var isMultiWindowMode: Boolean = false
- private var transposeLayoutWithOrientation: Boolean = false
- private var useTwoPanels: Boolean = false
- private var isGestureMode: Boolean = true
-
- @Before
- fun setUp() {
- context = ApplicationProvider.getApplicationContext()
- // make sure to reset values
- useTwoPanels = false
- }
-
- @Test
- fun qsbWidth_is_match_parent_for_phones() {
- initializeVarsForPhone()
-
- val dp = DeviceProfile(
- context,
- inv,
- info,
- windowBounds,
- isMultiWindowMode,
- transposeLayoutWithOrientation,
- useTwoPanels,
- isGestureMode
- )
-
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.qsbWidth).isEqualTo(0)
- }
-
- @Test
- fun qsbWidth_is_match_parent_for_tablet_portrait() {
- initializeVarsForLargeTablet()
-
- val dp = DeviceProfile(
- context,
- inv,
- info,
- windowBounds,
- isMultiWindowMode,
- transposeLayoutWithOrientation,
- useTwoPanels,
- isGestureMode
- )
-
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.qsbWidth).isEqualTo(0)
- }
-
- @Test
- fun qsbWidth_has_size_for_large_tablet_landscape() {
- initializeVarsForLargeTablet(true)
-
- val dp = DeviceProfile(
- context,
- inv,
- info,
- windowBounds,
- isMultiWindowMode,
- transposeLayoutWithOrientation,
- useTwoPanels,
- isGestureMode
- )
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.qsbWidth).isGreaterThan(0)
- } else {
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.qsbWidth).isEqualTo(0)
- }
- }
-
- /**
- * This test is to make sure that two panels don't inline the QSB as tablets do
- */
- @Test
- fun qsbWidth_is_match_parent_for_small_two_panel_landscape() {
- initializeVarsForSmallTablet(true)
- useTwoPanels = true
-
- val dp = DeviceProfile(
- context,
- inv,
- info,
- windowBounds,
- isMultiWindowMode,
- transposeLayoutWithOrientation,
- useTwoPanels,
- isGestureMode
- )
-
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.qsbWidth).isEqualTo(0)
- }
-
- private fun initializeVarsForPhone(isLandscape: Boolean = false) {
- val (x, y) = if (isLandscape)
- Pair(3120, 1440)
- else
- Pair(1440, 3120)
-
- windowBounds = WindowBounds(x, y, x, y - 100, 0)
-
- `when`(info.isTablet(any())).thenReturn(false)
- `when`(info.isLargeTablet(any())).thenReturn(false)
-
- scalableInvariantDeviceProfile()
- }
-
- private fun initializeVarsForSmallTablet(isLandscape: Boolean = false) {
- val (x, y) = if (isLandscape)
- Pair(2560, 1600)
- else
- Pair(1600, 2560)
-
- windowBounds = WindowBounds(x, y, x, y - 100, 0)
-
- `when`(info.isTablet(any())).thenReturn(true)
- `when`(info.isLargeTablet(any())).thenReturn(false)
-
- scalableInvariantDeviceProfile()
- }
-
- private fun initializeVarsForLargeTablet(isLandscape: Boolean = false) {
- val (x, y) = if (isLandscape)
- Pair(2560, 1600)
- else
- Pair(1600, 2560)
-
- windowBounds = WindowBounds(x, y, x, y - 100, 0)
-
- `when`(info.isTablet(any())).thenReturn(true)
- `when`(info.isLargeTablet(any())).thenReturn(true)
-
- scalableInvariantDeviceProfile()
- }
-
- /**
- * A very generic grid, just to make qsb tests work. For real calculations, make sure to use
- * values that better represent a real grid.
- */
- private fun scalableInvariantDeviceProfile() {
- inv = InvariantDeviceProfile().apply {
- isScalable = true
- numColumns = 5
- numRows = 5
- horizontalMargin = FloatArray(4) { 22f }
- borderSpaces = listOf(
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f)
- ).toTypedArray()
- allAppsBorderSpaces = listOf(
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f)
- ).toTypedArray()
- hotseatBorderSpaces = FloatArray(4) { 16f }
- iconSize = FloatArray(4) { 56f }
- allAppsIconSize = FloatArray(4) { 56f }
- iconTextSize = FloatArray(4) { 14f }
- allAppsIconTextSize = FloatArray(4) { 14f }
- minCellSize = listOf(
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f)
- ).toTypedArray()
- allAppsCellSize = listOf(
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f)
- ).toTypedArray()
- }
- }
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/HotseatSizeTest.kt b/tests/src/com/android/launcher3/HotseatSizeTest.kt
new file mode 100644
index 0000000000..ca697d7c96
--- /dev/null
+++ b/tests/src/com/android/launcher3/HotseatSizeTest.kt
@@ -0,0 +1,186 @@
+/*
+ * 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
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.`when` as whenever
+
+/**
+ * Test for [DeviceProfile]
+ */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HotseatSizeTest : DeviceProfileBaseTest() {
+
+ @Test
+ fun hotseat_size_is_normal_for_handhelds() {
+ initializeVarsForPhone()
+ inv = newScalableInvariantDeviceProfile().apply {
+ deviceType = TYPE_PHONE
+ }
+
+ val dp = newDP()
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(5)
+ }
+
+ @Test
+ fun hotseat_size_is_max_for_foldables() {
+ initializeVarsForTablet(isLandscape = true)
+ inv = newScalableInvariantDeviceProfile().apply {
+ deviceType = TYPE_MULTI_DISPLAY
+ }
+ useTwoPanels = true
+
+ val dp = newDP()
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ }
+
+ @Test
+ fun hotseat_size_is_shrunk_if_needed() {
+ initializeVarsForTablet(isLandscape = true)
+ inv = newScalableInvariantDeviceProfile().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(4)
+ } 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() {
+ initializeVarsForTablet()
+ inv = newScalableInvariantDeviceProfile().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(4)
+ } else { // Launcher3 doesn't have QSB height
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ }
+ }
+
+ @Test
+ fun hotseat_size_is_default_when_folded() {
+ initializeVarsForPhone()
+ inv = newScalableInvariantDeviceProfile().apply {
+ deviceType = TYPE_MULTI_DISPLAY
+ }
+ useTwoPanels = true
+
+ val dp = newDP()
+
+ assertThat(dp.numShownHotseatIcons).isEqualTo(5)
+ }
+
+ @Test
+ fun hotseat_size_is_shrunk_if_needed_on_tablet() {
+ initializeVarsForTablet(isLandscape = true)
+ inv = newScalableInvariantDeviceProfile().apply {
+ deviceType = TYPE_TABLET
+ inlineQsb = booleanArrayOf(
+ false,
+ true, // landscape
+ false,
+ false
+ )
+ }
+
+ isGestureMode = false
+ val dp = newDP()
+
+ if (dp.hotseatQsbHeight > 0) {
+ assertThat(dp.isQsbInline).isTrue()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(4)
+ } else { // Launcher3 doesn't have QSB height
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(5)
+ }
+ }
+
+ /**
+ * 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 = newScalableInvariantDeviceProfile().apply {
+ deviceType = TYPE_TABLET
+ inlineQsb = booleanArrayOf(
+ false,
+ true, // landscape
+ false,
+ false
+ )
+ }
+
+ isGestureMode = false
+ val dp = newDP()
+
+ if (dp.hotseatQsbHeight > 0) {
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(4)
+ } else { // Launcher3 doesn't have QSB height
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.numShownHotseatIcons).isEqualTo(5)
+ }
+ }
+
+} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/InlineQsbTest.kt b/tests/src/com/android/launcher3/InlineQsbTest.kt
new file mode 100644
index 0000000000..e00dca86e2
--- /dev/null
+++ b/tests/src/com/android/launcher3/InlineQsbTest.kt
@@ -0,0 +1,105 @@
+/*
+ * 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.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test for [DeviceProfile]
+ */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class InlineQsbTest : DeviceProfileBaseTest() {
+
+ @Test
+ fun qsbWidth_is_match_parent_for_phones() {
+ initializeVarsForPhone()
+
+ val dp = newDP()
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.qsbWidth).isEqualTo(0)
+ }
+
+ @Test
+ fun qsbWidth_is_match_parent_for_tablet_portrait() {
+ initializeVarsForTablet()
+ inv = newScalableInvariantDeviceProfile().apply {
+ inlineQsb = booleanArrayOf(
+ false,
+ true, // landscape
+ false,
+ false
+ )
+ }
+
+ val dp = DeviceProfile(
+ context,
+ inv,
+ info,
+ windowBounds,
+ isMultiWindowMode,
+ transposeLayoutWithOrientation,
+ useTwoPanels,
+ isGestureMode
+ )
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.qsbWidth).isEqualTo(0)
+ }
+
+ @Test
+ fun qsbWidth_has_size_for_tablet_landscape() {
+ initializeVarsForTablet(isLandscape = true)
+ inv = newScalableInvariantDeviceProfile().apply {
+ inlineQsb = booleanArrayOf(
+ false,
+ true, // landscape
+ false,
+ false
+ )
+ }
+
+ val dp = newDP()
+
+ if (dp.hotseatQsbHeight > 0) {
+ assertThat(dp.isQsbInline).isTrue()
+ assertThat(dp.qsbWidth).isGreaterThan(0)
+ } else { // Launcher3 doesn't have QSB height
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.qsbWidth).isEqualTo(0)
+ }
+ }
+
+ /**
+ * This test is to make sure that a tablet doesn't inline the QSB if the layout doesn't support
+ */
+ @Test
+ fun qsbWidth_is_match_parent_for_tablet_landscape_without_inline() {
+ initializeVarsForTablet(isLandscape = true)
+ useTwoPanels = true
+
+ val dp = newDP()
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.qsbWidth).isEqualTo(0)
+ }
+
+} \ No newline at end of file