mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 02:38:20 +00:00
Merge "Create specs for hotseat" into udc-qpr-dev
This commit is contained in:
@@ -202,6 +202,7 @@
|
||||
<attr name="demoModeLayoutId" format="reference" />
|
||||
<attr name="isScalable" format="boolean" />
|
||||
<attr name="devicePaddingId" format="reference" />
|
||||
|
||||
<!-- File that contains the specs for the workspace.
|
||||
Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
|
||||
<attr name="workspaceSpecsId" format="reference" />
|
||||
@@ -210,11 +211,14 @@
|
||||
Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
|
||||
<attr name="allAppsSpecsId" format="reference" />
|
||||
<attr name="allAppsSpecsTwoPanelId" format="reference" />
|
||||
|
||||
<!-- File that contains the specs for the workspace.
|
||||
Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
|
||||
<attr name="folderSpecsId" format="reference" />
|
||||
<attr name="folderSpecsTwoPanelId" format="reference" />
|
||||
<!-- File that contains the specs for hotseat bar.
|
||||
Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
|
||||
<attr name="hotseatSpecsId" format="reference" />
|
||||
<attr name="hotseatSpecsTwoPanelId" format="reference" />
|
||||
|
||||
<!-- By default all categories are enabled -->
|
||||
<attr name="deviceCategory" format="integer">
|
||||
@@ -278,6 +282,11 @@
|
||||
<attr name="maxAvailableSize" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="HotseatSpec">
|
||||
<attr name="specType" />
|
||||
<attr name="maxAvailableSize" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="SizeSpec">
|
||||
<attr name="fixedSize" format="dimension" />
|
||||
<attr name="ofAvailableSpace" format="float" />
|
||||
|
||||
@@ -56,8 +56,10 @@ import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.responsive.AllAppsSpecs;
|
||||
import com.android.launcher3.responsive.CalculatedAllAppsSpec;
|
||||
import com.android.launcher3.responsive.CalculatedFolderSpec;
|
||||
import com.android.launcher3.responsive.CalculatedHotseatSpec;
|
||||
import com.android.launcher3.responsive.CalculatedWorkspaceSpec;
|
||||
import com.android.launcher3.responsive.FolderSpecs;
|
||||
import com.android.launcher3.responsive.HotseatSpecs;
|
||||
import com.android.launcher3.responsive.WorkspaceSpecs;
|
||||
import com.android.launcher3.uioverrides.ApiWrapper;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
@@ -121,6 +123,7 @@ public class DeviceProfile {
|
||||
private CalculatedAllAppsSpec mAllAppsResponsiveHeightSpec;
|
||||
private CalculatedFolderSpec mResponsiveFolderWidthSpec;
|
||||
private CalculatedFolderSpec mResponsiveFolderHeightSpec;
|
||||
private CalculatedHotseatSpec mResponsiveHotseatSpec;
|
||||
|
||||
/**
|
||||
* The maximum amount of left/right workspace padding as a percentage of the screen width.
|
||||
@@ -316,7 +319,8 @@ public class DeviceProfile {
|
||||
// TODO(b/241386436): shouldn't change any launcher behaviour
|
||||
mIsResponsiveGrid = inv.workspaceSpecsId != INVALID_RESOURCE_HANDLE
|
||||
&& inv.allAppsSpecsId != INVALID_RESOURCE_HANDLE
|
||||
&& inv.folderSpecsId != INVALID_RESOURCE_HANDLE;
|
||||
&& inv.folderSpecsId != INVALID_RESOURCE_HANDLE
|
||||
&& inv.hotseatSpecsId != INVALID_RESOURCE_HANDLE;
|
||||
|
||||
mIsScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
|
||||
// Determine device posture.
|
||||
@@ -495,7 +499,17 @@ public class DeviceProfile {
|
||||
|
||||
int hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics);
|
||||
int minQsbMargin = res.getDimensionPixelSize(R.dimen.min_qsb_margin);
|
||||
hotseatQsbSpace = pxFromDp(inv.hotseatQsbSpace[mTypeIndex], mMetrics);
|
||||
|
||||
if (mIsResponsiveGrid) {
|
||||
HotseatSpecs hotseatSpecs =
|
||||
HotseatSpecs.create(new ResourceHelper(context,
|
||||
isTwoPanels ? inv.hotseatSpecsTwoPanelId : inv.hotseatSpecsId));
|
||||
mResponsiveHotseatSpec = hotseatSpecs.getCalculatedHeightSpec(heightPx);
|
||||
hotseatQsbSpace = mResponsiveHotseatSpec.getHotseatQsbSpace();
|
||||
} else {
|
||||
hotseatQsbSpace = pxFromDp(inv.hotseatQsbSpace[mTypeIndex], mMetrics);
|
||||
}
|
||||
|
||||
// Have a little space between the inset and the QSB
|
||||
if (mInsets.bottom + minQsbMargin > hotseatBarBottomSpace) {
|
||||
int availableSpace = hotseatQsbSpace - (mInsets.bottom - hotseatBarBottomSpace);
|
||||
@@ -1985,6 +1999,7 @@ public class DeviceProfile {
|
||||
+ mAllAppsResponsiveWidthSpec.toString());
|
||||
writer.println(prefix + "\tmResponsiveFolderHeightSpec:" + mResponsiveFolderHeightSpec);
|
||||
writer.println(prefix + "\tmResponsiveFolderWidthSpec:" + mResponsiveFolderWidthSpec);
|
||||
writer.println(prefix + "\tmResponsiveHotseatSpec:" + mResponsiveHotseatSpec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -190,6 +190,8 @@ public class InvariantDeviceProfile {
|
||||
public int folderSpecsId = INVALID_RESOURCE_HANDLE;
|
||||
@XmlRes
|
||||
public int folderSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
|
||||
public int hotseatSpecsId = INVALID_RESOURCE_HANDLE;
|
||||
public int hotseatSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
|
||||
|
||||
public String dbFile;
|
||||
public int defaultLayoutId;
|
||||
@@ -369,6 +371,8 @@ public class InvariantDeviceProfile {
|
||||
allAppsSpecsTwoPanelId = closestProfile.mAllAppsSpecsTwoPanelId;
|
||||
folderSpecsId = closestProfile.mFolderSpecsId;
|
||||
folderSpecsTwoPanelId = closestProfile.mFolderSpecsTwoPanelId;
|
||||
hotseatSpecsId = closestProfile.mHotseatSpecsId;
|
||||
hotseatSpecsTwoPanelId = closestProfile.mHotseatSpecsTwoPanelId;
|
||||
this.deviceType = deviceType;
|
||||
|
||||
inlineNavButtonsEndSpacing = closestProfile.inlineNavButtonsEndSpacing;
|
||||
@@ -820,6 +824,8 @@ public class InvariantDeviceProfile {
|
||||
private final int mAllAppsSpecsTwoPanelId;
|
||||
private final int mFolderSpecsId;
|
||||
private final int mFolderSpecsTwoPanelId;
|
||||
private final int mHotseatSpecsId;
|
||||
private final int mHotseatSpecsTwoPanelId;
|
||||
|
||||
public GridOption(Context context, AttributeSet attrs) {
|
||||
TypedArray a = context.obtainStyledAttributes(
|
||||
@@ -897,6 +903,11 @@ public class InvariantDeviceProfile {
|
||||
mFolderSpecsTwoPanelId = a.getResourceId(
|
||||
R.styleable.GridDisplayOption_folderSpecsTwoPanelId,
|
||||
INVALID_RESOURCE_HANDLE);
|
||||
mHotseatSpecsId = a.getResourceId(
|
||||
R.styleable.GridDisplayOption_hotseatSpecsId, INVALID_RESOURCE_HANDLE);
|
||||
mHotseatSpecsTwoPanelId = a.getResourceId(
|
||||
R.styleable.GridDisplayOption_hotseatSpecsTwoPanelId,
|
||||
INVALID_RESOURCE_HANDLE);
|
||||
} else {
|
||||
mWorkspaceSpecsId = INVALID_RESOURCE_HANDLE;
|
||||
mWorkspaceSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
|
||||
@@ -904,6 +915,8 @@ public class InvariantDeviceProfile {
|
||||
mAllAppsSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
|
||||
mFolderSpecsId = INVALID_RESOURCE_HANDLE;
|
||||
mFolderSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
|
||||
mHotseatSpecsId = INVALID_RESOURCE_HANDLE;
|
||||
mHotseatSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
|
||||
}
|
||||
|
||||
int inlineForRotation = a.getInt(R.styleable.GridDisplayOption_inlineQsb,
|
||||
|
||||
122
src/com/android/launcher3/responsive/HotseatSpecs.kt
Normal file
122
src/com/android/launcher3/responsive/HotseatSpecs.kt
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.responsive
|
||||
|
||||
import android.content.res.TypedArray
|
||||
import android.util.Log
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.util.ResourceHelper
|
||||
|
||||
class HotseatSpecs(val specs: List<HotseatSpec>) {
|
||||
|
||||
fun getCalculatedHeightSpec(availableHeight: Int): CalculatedHotseatSpec {
|
||||
val spec = specs.firstOrNull { availableHeight <= it.maxAvailableSize }
|
||||
check(spec != null) { "No available height spec found within $availableHeight." }
|
||||
return CalculatedHotseatSpec(availableHeight, spec)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val XML_HOTSEAT_SPEC = "hotseatSpec"
|
||||
|
||||
@JvmStatic
|
||||
fun create(resourceHelper: ResourceHelper): HotseatSpecs {
|
||||
val parser = ResponsiveSpecsParser(resourceHelper)
|
||||
val specs = parser.parseXML(XML_HOTSEAT_SPEC, ::HotseatSpec)
|
||||
return HotseatSpecs(specs.filter { it.specType == ResponsiveSpec.SpecType.HEIGHT })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class HotseatSpec(
|
||||
val maxAvailableSize: Int,
|
||||
val specType: ResponsiveSpec.SpecType,
|
||||
val hotseatQsbSpace: SizeSpec
|
||||
) {
|
||||
|
||||
init {
|
||||
check(isValid()) { "Invalid HotseatSpec found." }
|
||||
}
|
||||
|
||||
constructor(
|
||||
attrs: TypedArray,
|
||||
specs: Map<String, SizeSpec>
|
||||
) : this(
|
||||
maxAvailableSize =
|
||||
attrs.getDimensionPixelSize(R.styleable.ResponsiveSpec_maxAvailableSize, 0),
|
||||
specType =
|
||||
ResponsiveSpec.SpecType.values()[
|
||||
attrs.getInt(
|
||||
R.styleable.ResponsiveSpec_specType,
|
||||
ResponsiveSpec.SpecType.HEIGHT.ordinal
|
||||
)],
|
||||
hotseatQsbSpace = specs.getOrError(SizeSpec.XmlTags.HOTSEAT_QSB_SPACE)
|
||||
)
|
||||
|
||||
fun isValid(): Boolean {
|
||||
if (maxAvailableSize <= 0) {
|
||||
Log.e(LOG_TAG, "${this::class.simpleName}#isValid - maxAvailableSize <= 0")
|
||||
return false
|
||||
}
|
||||
|
||||
// All specs need to be individually valid
|
||||
if (!allSpecsAreValid()) {
|
||||
Log.e(LOG_TAG, "${this::class.simpleName}#isValid - !allSpecsAreValid()")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun allSpecsAreValid(): Boolean {
|
||||
return hotseatQsbSpace.isValid() && hotseatQsbSpace.onlyFixedSize()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val LOG_TAG = "HotseatSpec"
|
||||
}
|
||||
}
|
||||
|
||||
class CalculatedHotseatSpec(val availableSpace: Int, val spec: HotseatSpec) {
|
||||
|
||||
var hotseatQsbSpace: Int = 0
|
||||
private set
|
||||
|
||||
init {
|
||||
hotseatQsbSpace = spec.hotseatQsbSpace.getCalculatedValue(availableSpace)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = availableSpace.hashCode()
|
||||
result = 31 * result + hotseatQsbSpace.hashCode()
|
||||
result = 31 * result + spec.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is CalculatedHotseatSpec &&
|
||||
availableSpace == other.availableSpace &&
|
||||
hotseatQsbSpace == other.hotseatQsbSpace &&
|
||||
spec == other.spec
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "${this::class.simpleName}(" +
|
||||
"availableSpace=$availableSpace, hotseatQsbSpace=$hotseatQsbSpace, " +
|
||||
"${spec::class.simpleName}.maxAvailableSize=${spec.maxAvailableSize}" +
|
||||
")"
|
||||
}
|
||||
}
|
||||
@@ -107,11 +107,20 @@ data class SizeSpec(
|
||||
return true
|
||||
}
|
||||
|
||||
fun onlyFixedSize(): Boolean {
|
||||
if (ofAvailableSpace > 0 || ofRemainderSpace > 0 || matchWorkspace) {
|
||||
Log.e(TAG, "SizeSpec#onlyFixedSize - only fixed size allowed for this tag")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
object XmlTags {
|
||||
const val START_PADDING = "startPadding"
|
||||
const val END_PADDING = "endPadding"
|
||||
const val GUTTER = "gutter"
|
||||
const val CELL_SIZE = "cellSize"
|
||||
const val HOTSEAT_QSB_SPACE = "hotseatQsbSpace"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
30
tests/res/xml/invalid_hotseat_file_case_1.xml
Normal file
30
tests/res/xml/invalid_hotseat_file_case_1.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2023 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.
|
||||
-->
|
||||
<hotseatSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<hotseatSpec
|
||||
launcher:specType="height"
|
||||
launcher:maxAvailableSize="847dp">
|
||||
<hotseatQsbSpace launcher:ofAvailableSpace="1" />
|
||||
</hotseatSpec>
|
||||
|
||||
<hotseatSpec
|
||||
launcher:specType="height"
|
||||
launcher:maxAvailableSize="9999dp">
|
||||
<hotseatQsbSpace launcher:fixedSize="36dp" />
|
||||
</hotseatSpec>
|
||||
|
||||
</hotseatSpecs>
|
||||
30
tests/res/xml/valid_hotseat_file.xml
Normal file
30
tests/res/xml/valid_hotseat_file.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2023 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.
|
||||
-->
|
||||
<hotseatSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<hotseatSpec
|
||||
launcher:specType="height"
|
||||
launcher:maxAvailableSize="847dp">
|
||||
<hotseatQsbSpace launcher:fixedSize="24dp" />
|
||||
</hotseatSpec>
|
||||
|
||||
<hotseatSpec
|
||||
launcher:specType="height"
|
||||
launcher:maxAvailableSize="9999dp">
|
||||
<hotseatQsbSpace launcher:fixedSize="36dp" />
|
||||
</hotseatSpec>
|
||||
|
||||
</hotseatSpecs>
|
||||
@@ -22,6 +22,7 @@ import android.graphics.Rect
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Surface
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.launcher3.testing.shared.ResourceUtils
|
||||
import com.android.launcher3.util.DisplayController
|
||||
import com.android.launcher3.util.NavigationMode
|
||||
import com.android.launcher3.util.WindowBounds
|
||||
@@ -320,4 +321,12 @@ abstract class AbstractDeviceProfileTest {
|
||||
private fun writeToDevice(context: Context, fileName: String, content: String) {
|
||||
File(context.getDir("dumpTests", Context.MODE_PRIVATE), fileName).writeText(content)
|
||||
}
|
||||
|
||||
protected fun Float.dpToPx(): Float {
|
||||
return ResourceUtils.pxFromDp(this, context!!.resources.displayMetrics).toFloat()
|
||||
}
|
||||
|
||||
protected fun Int.dpToPx(): Int {
|
||||
return ResourceUtils.pxFromDp(this.toFloat(), context!!.resources.displayMetrics)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.android.launcher3.AbstractDeviceProfileTest
|
||||
import com.android.launcher3.testing.shared.ResourceUtils
|
||||
import com.android.launcher3.tests.R
|
||||
import com.android.launcher3.util.TestResourceHelper
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
@@ -118,8 +117,4 @@ class CalculatedFolderSpecsTest : AbstractDeviceProfileTest() {
|
||||
assertThat(cellSizePx).isEqualTo(calculatedWorkspace.cellSizePx)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.dpToPx(): Int {
|
||||
return ResourceUtils.pxFromDp(this.toFloat(), context!!.resources.displayMetrics)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.responsive
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.android.launcher3.AbstractDeviceProfileTest
|
||||
import com.android.launcher3.tests.R as TestR
|
||||
import com.android.launcher3.util.TestResourceHelper
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CalculatedHotseatSpecTest : AbstractDeviceProfileTest() {
|
||||
override val runningContext: Context = InstrumentationRegistry.getInstrumentation().context
|
||||
|
||||
/**
|
||||
* This test tests:
|
||||
* - (height spec) gets the correct breakpoint from the XML - skips the first breakpoint
|
||||
*/
|
||||
@Test
|
||||
fun normalPhone_returnsSecondBreakpointSpec() {
|
||||
val deviceSpec = deviceSpecs["phone"]!!
|
||||
initializeVarsForPhone(deviceSpec)
|
||||
|
||||
// Hotseat uses the whole device height
|
||||
val availableHeight = deviceSpec.naturalSize.second
|
||||
|
||||
val hotseatSpecs =
|
||||
HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_file))
|
||||
val heightSpec = hotseatSpecs.getCalculatedHeightSpec(availableHeight)
|
||||
|
||||
assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
|
||||
assertThat(heightSpec.hotseatQsbSpace).isEqualTo(95)
|
||||
}
|
||||
|
||||
/**
|
||||
* This test tests:
|
||||
* - (height spec) gets the correct breakpoint from the XML - use the first breakpoint
|
||||
*/
|
||||
@Test
|
||||
fun smallPhone_returnsFirstBreakpointSpec() {
|
||||
val deviceSpec = deviceSpecs["phone"]!!
|
||||
deviceSpec.densityDpi = 540 // larger display size
|
||||
initializeVarsForPhone(deviceSpec)
|
||||
|
||||
// Hotseat uses the whole device height
|
||||
val availableHeight = deviceSpec.naturalSize.second
|
||||
|
||||
val hotseatSpecs =
|
||||
HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_file))
|
||||
val heightSpec = hotseatSpecs.getCalculatedHeightSpec(availableHeight)
|
||||
|
||||
assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
|
||||
assertThat(heightSpec.hotseatQsbSpace).isEqualTo(81)
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.android.launcher3.AbstractDeviceProfileTest
|
||||
import com.android.launcher3.responsive.ResponsiveSpec.SpecType
|
||||
import com.android.launcher3.testing.shared.ResourceUtils
|
||||
import com.android.launcher3.tests.R
|
||||
import com.android.launcher3.util.TestResourceHelper
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
@@ -249,12 +248,4 @@ class FolderSpecsTest : AbstractDeviceProfileTest() {
|
||||
val folderSpecs = FolderSpecs.create(resourceHelper)
|
||||
folderSpecs.getCalculatedHeightSpec(cells, availableSpace, calculatedWorkspaceSpec)
|
||||
}
|
||||
|
||||
private fun Float.dpToPx(): Float {
|
||||
return ResourceUtils.pxFromDp(this, context!!.resources.displayMetrics).toFloat()
|
||||
}
|
||||
|
||||
private fun Int.dpToPx(): Int {
|
||||
return ResourceUtils.pxFromDp(this.toFloat(), context!!.resources.displayMetrics)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.responsive
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.android.launcher3.AbstractDeviceProfileTest
|
||||
import com.android.launcher3.tests.R as TestR
|
||||
import com.android.launcher3.util.TestResourceHelper
|
||||
import com.android.systemui.util.dpToPx
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class HotseatSpecsTest : AbstractDeviceProfileTest() {
|
||||
override val runningContext: Context = InstrumentationRegistry.getInstrumentation().context
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
initializeVarsForPhone(deviceSpecs["phone"]!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseValidFile() {
|
||||
val hotseatSpecs =
|
||||
HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_file))
|
||||
assertThat(hotseatSpecs.specs.size).isEqualTo(2)
|
||||
|
||||
val expectedSpecs =
|
||||
listOf(
|
||||
HotseatSpec(
|
||||
maxAvailableSize = 847.dpToPx(),
|
||||
specType = ResponsiveSpec.SpecType.HEIGHT,
|
||||
hotseatQsbSpace = SizeSpec(24f.dpToPx())
|
||||
),
|
||||
HotseatSpec(
|
||||
maxAvailableSize = 9999.dpToPx(),
|
||||
specType = ResponsiveSpec.SpecType.HEIGHT,
|
||||
hotseatQsbSpace = SizeSpec(36f.dpToPx())
|
||||
),
|
||||
)
|
||||
|
||||
assertThat(hotseatSpecs.specs.size).isEqualTo(expectedSpecs.size)
|
||||
assertThat(hotseatSpecs.specs[0]).isEqualTo(expectedSpecs[0])
|
||||
assertThat(hotseatSpecs.specs[1]).isEqualTo(expectedSpecs[1])
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException::class)
|
||||
fun parseInvalidFile_spaceIsNotFixedSize_throwsError() {
|
||||
HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.invalid_hotseat_file_case_1))
|
||||
}
|
||||
}
|
||||
@@ -139,4 +139,20 @@ class SizeSpecTest : AbstractDeviceProfileTest() {
|
||||
assertThat(instance.isValid()).isEqualTo(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyFixedSize() {
|
||||
assertThat(SizeSpec(fixedSize = 16f).onlyFixedSize()).isEqualTo(true)
|
||||
|
||||
val combinations =
|
||||
listOf(
|
||||
SizeSpec(0f, 1.1f, 0f, false),
|
||||
SizeSpec(0f, 0f, 1.1f, false),
|
||||
SizeSpec(0f, 0f, 0f, true)
|
||||
)
|
||||
|
||||
for (instance in combinations) {
|
||||
assertThat(instance.onlyFixedSize()).isEqualTo(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user