Update SizeSpec attributes to accept max size threshold

Add maxSize attribute to SizeSpec to limit the cell size up to a max size when matchWorkspace is true. The same validation was added when using fixedSize, ofAvailableSpace and ofRemainderSpace, so they could have a maxSize as a threshold.

Bug: 284155638
Flag: ENABLE_RESPONSIVE_WORKSPACE
Test: SizeSpecTest
Test: WorkspaceSpecsTest
Change-Id: I113657c241e6618eb3e501243412d8c5626fc3d5
This commit is contained in:
Jordan Silva
2023-06-13 15:27:40 +01:00
parent 7ae9e3a6f5
commit 1b336110a4
5 changed files with 86 additions and 36 deletions

View File

@@ -257,6 +257,7 @@
<attr name="ofAvailableSpace" format="float" />
<attr name="ofRemainderSpace" format="float" />
<attr name="matchWorkspace" format="boolean" />
<attr name="maxSize" format="dimension" />
</declare-styleable>
<declare-styleable name="FolderSpec">

View File

@@ -15,22 +15,27 @@ import kotlin.math.roundToInt
* @param ofAvailableSpace a percentage of the available space
* @param ofRemainderSpace a percentage of the remaining space (available space minus used space)
* @param matchWorkspace indicates whether the workspace value will be used or not.
* @param maxSize restricts the maximum value allowed for the [SizeSpec].
*/
data class SizeSpec(
val fixedSize: Float = 0f,
val ofAvailableSpace: Float = 0f,
val ofRemainderSpace: Float = 0f,
val matchWorkspace: Boolean = false
val matchWorkspace: Boolean = false,
val maxSize: Int = Int.MAX_VALUE
) {
/** Retrieves the correct value for [SizeSpec]. */
fun getCalculatedValue(availableSpace: Int, workspaceValue: Int): Int {
return when {
fixedSize > 0 -> fixedSize.roundToInt()
ofAvailableSpace > 0 -> (ofAvailableSpace * availableSpace).roundToInt()
matchWorkspace -> workspaceValue
else -> 0
}
val calculatedValue =
when {
fixedSize > 0 -> fixedSize.roundToInt()
matchWorkspace -> workspaceValue
ofAvailableSpace > 0 -> (ofAvailableSpace * availableSpace).roundToInt()
else -> 0
}
return calculatedValue.coerceAtMost(maxSize)
}
/**
@@ -38,11 +43,14 @@ data class SizeSpec(
* is 0, returns a default value.
*/
fun getRemainderSpaceValue(remainderSpace: Int, defaultValue: Int): Int {
return if (ofRemainderSpace > 0) {
(ofRemainderSpace * remainderSpace).roundToInt()
} else {
defaultValue
}
val remainderSpaceValue =
if (ofRemainderSpace > 0) {
(ofRemainderSpace * remainderSpace).roundToInt()
} else {
defaultValue
}
return remainderSpaceValue.coerceAtMost(maxSize)
}
fun isValid(): Boolean {
@@ -69,12 +77,17 @@ data class SizeSpec(
return false
}
// Invalid fixed size
if (fixedSize < 0f) {
// Invalid fixed or max size
if (fixedSize < 0f || maxSize < 0f) {
Log.e(TAG, "SizeSpec#isValid - values should be bigger or equal to zero.")
return false
}
if (fixedSize > 0f && fixedSize > maxSize) {
Log.e(TAG, "SizeSpec#isValid - fixed size should be smaller than the max size.")
return false
}
return true
}
@@ -96,10 +109,12 @@ data class SizeSpec(
val ofAvailableSpace = getValue(styledAttrs, R.styleable.SizeSpec_ofAvailableSpace)
val ofRemainderSpace = getValue(styledAttrs, R.styleable.SizeSpec_ofRemainderSpace)
val matchWorkspace = styledAttrs.getBoolean(R.styleable.SizeSpec_matchWorkspace, false)
val maxSize =
styledAttrs.getDimensionPixelSize(R.styleable.SizeSpec_maxSize, Int.MAX_VALUE)
styledAttrs.recycle()
return SizeSpec(fixedSize, ofAvailableSpace, ofRemainderSpace, matchWorkspace)
return SizeSpec(fixedSize, ofAvailableSpace, ofRemainderSpace, matchWorkspace, maxSize)
}
}
}

View File

@@ -31,6 +31,7 @@
<attr name="ofAvailableSpace" format="float" />
<attr name="ofRemainderSpace" format="float" />
<attr name="matchWorkspace" format="boolean" />
<attr name="maxSize" format="dimension" />
</declare-styleable>
<declare-styleable name="FolderSpec">

View File

@@ -45,7 +45,12 @@ class SizeSpecTest : AbstractDeviceProfileTest() {
SizeSpec(0f, 1f, 0f, false),
SizeSpec(0f, 0f, 1f, false),
SizeSpec(0f, 0f, 0f, false),
SizeSpec(0f, 0f, 0f, true)
SizeSpec(0f, 0f, 0f, true),
SizeSpec(100f, 0f, 0f, false, 100),
SizeSpec(0f, 1f, 0f, false, 100),
SizeSpec(0f, 0f, 1f, false, 100),
SizeSpec(0f, 0f, 0f, false, 100),
SizeSpec(0f, 0f, 0f, true, 100)
)
for (instance in combinations) {
@@ -62,7 +67,12 @@ class SizeSpecTest : AbstractDeviceProfileTest() {
SizeSpec(100f) to 100,
SizeSpec(ofAvailableSpace = .5f) to (availableSpace * .5f).roundToInt(),
SizeSpec(ofRemainderSpace = .5f) to 0,
SizeSpec(matchWorkspace = true) to matchWorkspaceValue
SizeSpec(matchWorkspace = true) to matchWorkspaceValue,
// Restricts max size up to 10 (calculated value > 10)
SizeSpec(100f, maxSize = 10) to 10,
SizeSpec(ofAvailableSpace = .5f, maxSize = 10) to 10,
SizeSpec(ofRemainderSpace = .5f, maxSize = 10) to 0,
SizeSpec(matchWorkspace = true, maxSize = 10) to 10
)
for ((sizeSpec, expectedValue) in combinations) {
@@ -74,13 +84,18 @@ class SizeSpecTest : AbstractDeviceProfileTest() {
@Test
fun validate_getRemainderSpaceValue() {
val remainderSpace = 100
val defaultValue = 10
val defaultValue = 50
val combinations =
listOf(
SizeSpec(100f) to defaultValue,
SizeSpec(ofAvailableSpace = .5f) to defaultValue,
SizeSpec(ofRemainderSpace = .5f) to (remainderSpace * .5f).roundToInt(),
SizeSpec(matchWorkspace = true) to defaultValue
SizeSpec(matchWorkspace = true) to defaultValue,
// Restricts max size up to 10 (defaultValue > 10)
SizeSpec(100f, maxSize = 10) to 10,
SizeSpec(ofAvailableSpace = .5f, maxSize = 10) to 10,
SizeSpec(ofRemainderSpace = .5f, maxSize = 10) to 10,
SizeSpec(matchWorkspace = true, maxSize = 10) to 10,
)
for ((sizeSpec, expectedValue) in combinations) {
@@ -111,11 +126,13 @@ class SizeSpecTest : AbstractDeviceProfileTest() {
fun invalid_values() {
val combinations =
listOf(
SizeSpec(-1f, 0f, 0f, false),
SizeSpec(0f, 1.1f, 0f, false),
SizeSpec(0f, -0.1f, 0f, false),
SizeSpec(0f, 0f, 1.1f, false),
SizeSpec(0f, 0f, -0.1f, false),
SizeSpec(-1f, 0f, 0f, false)
SizeSpec(0f, 0f, 0f, false, -10),
SizeSpec(50f, 0f, 0f, false, 10)
)
for (instance in combinations) {

View File

@@ -51,19 +51,23 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"startPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"endPadding=SizeSpec(fixedSize=84.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"cellSize=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.15808, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false)" +
"matchWorkspace=false, " +
"maxSize=2147483647)" +
")"
)
assertThat(workspaceSpecs.workspaceHeightSpecList[1].toString())
@@ -74,19 +78,23 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"startPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"endPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=1.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"cellSize=SizeSpec(fixedSize=273.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false)" +
"matchWorkspace=false, " +
"maxSize=2147483647)" +
")"
)
assertThat(workspaceSpecs.workspaceHeightSpecList[2].toString())
@@ -97,19 +105,23 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"startPadding=SizeSpec(fixedSize=21.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"endPadding=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=1.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"cellSize=SizeSpec(fixedSize=273.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false)" +
"matchWorkspace=false, " +
"maxSize=2147483647)" +
")"
)
assertThat(workspaceSpecs.workspaceWidthSpecList.size).isEqualTo(1)
@@ -121,19 +133,23 @@ class WorkspaceSpecsTest : AbstractDeviceProfileTest() {
"startPadding=SizeSpec(fixedSize=58.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"endPadding=SizeSpec(fixedSize=58.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"gutter=SizeSpec(fixedSize=42.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.0, " +
"matchWorkspace=false), " +
"matchWorkspace=false, " +
"maxSize=2147483647), " +
"cellSize=SizeSpec(fixedSize=0.0, " +
"ofAvailableSpace=0.0, " +
"ofRemainderSpace=0.25, " +
"matchWorkspace=false)" +
"matchWorkspace=false, " +
"maxSize=2147483647)" +
")"
)
}