Merge "Simplify keyguard notification count logic" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f9e8a7fe57
@@ -417,7 +417,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
private NotificationShelf mShelf;
|
||||
private int mMaxDisplayedNotifications = -1;
|
||||
private float mKeyguardBottomPadding = -1;
|
||||
private float mKeyguardNotificationAvailableSpace = -1;
|
||||
@VisibleForTesting int mStatusBarHeight;
|
||||
private int mMinInteractionHeight;
|
||||
private final Rect mClipRect = new Rect();
|
||||
@@ -775,9 +774,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
y = (int) mMaxLayoutHeight;
|
||||
drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "mMaxLayoutHeight = " + y);
|
||||
|
||||
// The space between mTopPadding and mKeyguardBottomPadding determines the available space
|
||||
// for notifications on keyguard.
|
||||
if (mKeyguardBottomPadding >= 0) {
|
||||
y = getHeight() - (int) mKeyguardBottomPadding;
|
||||
drawDebugInfo(canvas, y, Color.GRAY,
|
||||
drawDebugInfo(canvas, y, Color.RED,
|
||||
/* label= */ "getHeight() - mKeyguardBottomPadding = " + y);
|
||||
}
|
||||
|
||||
@@ -789,7 +790,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
drawDebugInfo(canvas, y, Color.CYAN, /* label= */ "mAmbientState.getStackY() = " + y);
|
||||
|
||||
y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight());
|
||||
drawDebugInfo(canvas, y, Color.BLUE,
|
||||
drawDebugInfo(canvas, y, Color.LTGRAY,
|
||||
/* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight() = " + y);
|
||||
|
||||
y = (int) mAmbientState.getStackY() + mContentHeight;
|
||||
@@ -800,10 +801,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
drawDebugInfo(canvas, y, Color.YELLOW,
|
||||
/* label= */ "mAmbientState.getStackY() + mIntrinsicContentHeight = " + y);
|
||||
|
||||
y = (int) (mAmbientState.getStackY() + mKeyguardNotificationAvailableSpace);
|
||||
drawDebugInfo(canvas, y, Color.RED, /* label= */
|
||||
"mAmbientState.getStackY() + mKeyguardNotificationAvailableSpace = " + y);
|
||||
|
||||
drawDebugInfo(canvas, mRoundedRectClippingBottom, Color.DKGRAY,
|
||||
/* label= */ "mRoundedRectClippingBottom) = " + y);
|
||||
}
|
||||
@@ -2267,10 +2264,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||
private void updateContentHeight() {
|
||||
final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
|
||||
final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
|
||||
final int height =
|
||||
(int) scrimTopPadding + (int) mNotificationStackSizeCalculator.computeHeight(
|
||||
/* notificationStackScrollLayout= */ this, mMaxDisplayedNotifications,
|
||||
mShelf != null ? mShelf.getIntrinsicHeight() : 0);
|
||||
shelfIntrinsicHeight);
|
||||
mIntrinsicContentHeight = height;
|
||||
|
||||
// The topPadding can be bigger than the regular padding when qs is expanded, in that
|
||||
@@ -4914,15 +4912,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
mKeyguardBottomPadding = keyguardBottomPadding;
|
||||
}
|
||||
|
||||
/**
|
||||
* For debugging only. Enables to draw a line related to the available size for notifications in
|
||||
* keyguard.
|
||||
*/
|
||||
public void setKeyguardAvailableSpaceForDebug(float keyguardNotificationAvailableSpace) {
|
||||
mKeyguardNotificationAvailableSpace = keyguardNotificationAvailableSpace;
|
||||
}
|
||||
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||
public void setShouldShowShelfOnly(boolean shouldShowShelfOnly) {
|
||||
mShouldShowShelfOnly = shouldShowShelfOnly;
|
||||
|
||||
@@ -1305,12 +1305,6 @@ public class NotificationStackScrollLayoutController {
|
||||
mView.setKeyguardBottomPadding(keyguardBottomPadding);
|
||||
}
|
||||
|
||||
/** For debugging only. */
|
||||
public void mKeyguardNotificationAvailableSpaceForDebug(
|
||||
float keyguardNotificationAvailableSpace) {
|
||||
mView.setKeyguardAvailableSpaceForDebug(keyguardNotificationAvailableSpace);
|
||||
}
|
||||
|
||||
public RemoteInputController.Delegate createDelegate() {
|
||||
return new RemoteInputController.Delegate() {
|
||||
public void setRemoteInputActive(NotificationEntry entry,
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableView
|
||||
import com.android.systemui.util.children
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.properties.Delegates.notNull
|
||||
|
||||
private const val TAG = "NotificationStackSizeCalculator"
|
||||
@@ -51,9 +52,7 @@ constructor(
|
||||
*/
|
||||
private var maxKeyguardNotifications by notNull<Int>()
|
||||
|
||||
/**
|
||||
* Minimum space between two notifications, see [calculateGapAndDividerHeight].
|
||||
*/
|
||||
/** Minimum space between two notifications, see [calculateGapAndDividerHeight]. */
|
||||
private var dividerHeight by notNull<Int>()
|
||||
|
||||
init {
|
||||
@@ -61,55 +60,34 @@ constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the [availableSpace] constraint, calculates how many notification to show.
|
||||
* Given the [totalAvailableSpace] constraint, calculates how many notification to show.
|
||||
*
|
||||
* This number is only valid in keyguard.
|
||||
*
|
||||
* @param availableSpace space for notifications. This doesn't include the space for the shelf.
|
||||
* @param totalAvailableSpace space for notifications. This includes the space for the shelf.
|
||||
*/
|
||||
fun computeMaxKeyguardNotifications(
|
||||
stack: NotificationStackScrollLayout,
|
||||
availableSpace: Float,
|
||||
shelfHeight: Float
|
||||
totalAvailableSpace: Float,
|
||||
shelfIntrinsicHeight: Float
|
||||
): Int {
|
||||
val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
|
||||
|
||||
var maxNotifications =
|
||||
stackHeightSequence.lastIndexWhile { stackHeight -> stackHeight <= totalAvailableSpace }
|
||||
|
||||
if (onLockscreen()) {
|
||||
maxNotifications = min(maxKeyguardNotifications, maxNotifications)
|
||||
}
|
||||
|
||||
// Could be < 0 if the space available is less than the shelf size. Returns 0 in this case.
|
||||
maxNotifications = max(0, maxNotifications)
|
||||
log {
|
||||
"computeMaxKeyguardNotifications(" +
|
||||
"availableSpace=$availableSpace shelfHeight=$shelfHeight)"
|
||||
"availableSpace=$totalAvailableSpace" +
|
||||
" shelfHeight=$shelfIntrinsicHeight) -> $maxNotifications"
|
||||
}
|
||||
|
||||
val children: Sequence<ExpandableView> = stack.childrenSequence
|
||||
var remainingSpace: Float = availableSpace
|
||||
var count = 0
|
||||
var previous: ExpandableView? = null
|
||||
val onLockscreen = true
|
||||
val showableRows = children.filter { it.isShowable(onLockscreen) }
|
||||
val showableRowsCount = showableRows.count()
|
||||
log { "\tshowableRowsCount=$showableRowsCount "}
|
||||
|
||||
showableRows.forEachIndexed { i, current ->
|
||||
val spaceNeeded = current.spaceNeeded(count, previous, stack, onLockscreen)
|
||||
val spaceAfter = remainingSpace - spaceNeeded
|
||||
previous = current
|
||||
log { "\ti=$i spaceNeeded=$spaceNeeded remainingSpace=$remainingSpace " +
|
||||
"spaceAfter=$spaceAfter" }
|
||||
|
||||
if (remainingSpace - spaceNeeded >= 0 && count < maxKeyguardNotifications) {
|
||||
count += 1
|
||||
remainingSpace -= spaceNeeded
|
||||
} else if (remainingSpace - spaceNeeded > -shelfHeight && i == showableRowsCount - 1) {
|
||||
log { "Show all notifications. Shelf not needed." }
|
||||
// If this is the last one, and it fits using the space shelf would use, then we can
|
||||
// display it, as the shelf will not be needed (as all notifications are shown).
|
||||
return count + 1
|
||||
} else {
|
||||
log {
|
||||
"No more fit. Returning $count. Space used: ${availableSpace - remainingSpace}"
|
||||
}
|
||||
return count
|
||||
}
|
||||
}
|
||||
log { "All fit. Returning $count" }
|
||||
return count
|
||||
return maxNotifications
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,47 +97,60 @@ constructor(
|
||||
* @param stack stack containing notifications as children.
|
||||
* @param maxNotifications Maximum number of notifications. When reached, the others will go
|
||||
* into the shelf.
|
||||
* @param shelfHeight height of the shelf. It might be zero.
|
||||
* @param shelfIntrinsicHeight height of the shelf, without any padding. It might be zero.
|
||||
*
|
||||
* @return height of the stack, including shelf height, if needed.
|
||||
*/
|
||||
fun computeHeight(
|
||||
stack: NotificationStackScrollLayout,
|
||||
maxNotifications: Int,
|
||||
shelfHeight: Float
|
||||
shelfIntrinsicHeight: Float
|
||||
): Float {
|
||||
val children: Sequence<ExpandableView> = stack.childrenSequence
|
||||
val maxNotificationsArg = infiniteIfNegative(maxNotifications)
|
||||
val heightPerMaxNotifications =
|
||||
computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
|
||||
val height =
|
||||
heightPerMaxNotifications.elementAtOrElse(maxNotifications) {
|
||||
heightPerMaxNotifications.last() // Height with all notifications visible.
|
||||
}
|
||||
log { "computeHeight(maxNotifications=$maxNotifications) -> $height" }
|
||||
return height
|
||||
}
|
||||
|
||||
/** The ith result in the sequence is the height with ith max notifications. */
|
||||
private fun computeHeightPerNotificationLimit(
|
||||
stack: NotificationStackScrollLayout,
|
||||
shelfIntrinsicHeight: Float
|
||||
): Sequence<Float> = sequence {
|
||||
val children = stack.showableChildren().toList()
|
||||
var height = 0f
|
||||
var previous: ExpandableView? = null
|
||||
var count = 0
|
||||
val onLockscreen = onLockscreen()
|
||||
|
||||
log { "computeHeight(maxNotification=$maxNotifications, shelf=$shelfHeight" }
|
||||
children.filter { it.isShowable(onLockscreen) }.forEach { current ->
|
||||
if (count < maxNotificationsArg) {
|
||||
val spaceNeeded = current.spaceNeeded(count, previous, stack, onLockscreen)
|
||||
log { "\ti=$count spaceNeeded=$spaceNeeded" }
|
||||
height += spaceNeeded
|
||||
count += 1
|
||||
} else {
|
||||
height += current.calculateGapAndDividerHeight(stack, previous, count)
|
||||
height += shelfHeight
|
||||
log { "returning height with shelf -> $height" }
|
||||
return height
|
||||
}
|
||||
previous = current
|
||||
yield(dividerHeight + shelfIntrinsicHeight) // Only shelf.
|
||||
|
||||
children.forEachIndexed { i, currentNotification ->
|
||||
height += currentNotification.spaceNeeded(i, previous, stack, onLockscreen)
|
||||
previous = currentNotification
|
||||
|
||||
val shelfHeight =
|
||||
if (i == children.lastIndex) {
|
||||
0f // No shelf needed.
|
||||
} else {
|
||||
val spaceBeforeShelf =
|
||||
calculateGapAndDividerHeight(
|
||||
stack, previous = currentNotification, current = children[i + 1], i)
|
||||
spaceBeforeShelf + shelfIntrinsicHeight
|
||||
}
|
||||
|
||||
yield(height + shelfHeight)
|
||||
}
|
||||
log { "Returning height without shelf -> $height" }
|
||||
return height
|
||||
}
|
||||
|
||||
fun updateResources() {
|
||||
maxKeyguardNotifications =
|
||||
infiniteIfNegative(resources.getInteger(R.integer.keyguard_max_notification_count))
|
||||
|
||||
dividerHeight =
|
||||
max(1, resources.getDimensionPixelSize(R.dimen.notification_divider_height))
|
||||
dividerHeight = max(1, resources.getDimensionPixelSize(R.dimen.notification_divider_height))
|
||||
}
|
||||
|
||||
private val NotificationStackScrollLayout.childrenSequence: Sequence<ExpandableView>
|
||||
@@ -180,7 +171,7 @@ constructor(
|
||||
} else {
|
||||
intrinsicHeight.toFloat()
|
||||
}
|
||||
size += calculateGapAndDividerHeight(stack, previousView, visibleIndex)
|
||||
size += calculateGapAndDividerHeight(stack, previousView, current = this, visibleIndex)
|
||||
return size
|
||||
}
|
||||
|
||||
@@ -200,18 +191,22 @@ constructor(
|
||||
return true
|
||||
}
|
||||
|
||||
private fun ExpandableView.calculateGapAndDividerHeight(
|
||||
private fun calculateGapAndDividerHeight(
|
||||
stack: NotificationStackScrollLayout,
|
||||
previous: ExpandableView?,
|
||||
current: ExpandableView?,
|
||||
visibleIndex: Int
|
||||
) : Float {
|
||||
var height = stack.calculateGapHeight(previous, /* current= */ this, visibleIndex)
|
||||
): Float {
|
||||
var height = stack.calculateGapHeight(previous, current, visibleIndex)
|
||||
if (visibleIndex != 0) {
|
||||
height += dividerHeight
|
||||
}
|
||||
return height
|
||||
}
|
||||
|
||||
private fun NotificationStackScrollLayout.showableChildren() =
|
||||
this.childrenSequence.filter { it.isShowable(onLockscreen()) }
|
||||
|
||||
/**
|
||||
* Can a view be shown on the lockscreen when calculating the number of allowed notifications to
|
||||
* show?
|
||||
@@ -240,4 +235,8 @@ constructor(
|
||||
} else {
|
||||
v
|
||||
}
|
||||
|
||||
/** Returns the last index where [predicate] returns true, or -1 if it was always false. */
|
||||
private fun <T> Sequence<T>.lastIndexWhile(predicate: (T) -> Boolean): Int =
|
||||
takeWhile(predicate).count() - 1
|
||||
}
|
||||
|
||||
@@ -317,8 +317,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
private boolean mShouldUseSplitNotificationShade;
|
||||
// The bottom padding reserved for elements of the keyguard measuring notifications
|
||||
private float mKeyguardNotificationBottomPadding;
|
||||
// Space available for notifications.
|
||||
private float mKeyguardNotificationAvailableSpace;
|
||||
// Current max allowed keyguard notifications determined by measuring the panel
|
||||
private int mMaxAllowedKeyguardNotifications;
|
||||
|
||||
@@ -1245,8 +1243,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
mMaxAllowedKeyguardNotifications);
|
||||
mNotificationStackScrollLayoutController.setKeyguardBottomPaddingForDebug(
|
||||
mKeyguardNotificationBottomPadding);
|
||||
mNotificationStackScrollLayoutController.mKeyguardNotificationAvailableSpaceForDebug(
|
||||
mKeyguardNotificationAvailableSpace);
|
||||
} else {
|
||||
// no max when not on the keyguard
|
||||
mNotificationStackScrollLayoutController.setMaxDisplayedNotifications(-1);
|
||||
@@ -1468,13 +1464,11 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
* @return the maximum keyguard notifications that can fit on the screen
|
||||
*/
|
||||
private int computeMaxKeyguardNotifications() {
|
||||
int notificationPadding = Math.max(
|
||||
1, mResources.getDimensionPixelSize(R.dimen.notification_divider_height));
|
||||
float topPadding = mNotificationStackScrollLayoutController.getTopPadding();
|
||||
float shelfHeight =
|
||||
float shelfIntrinsicHeight =
|
||||
mNotificationShelfController.getVisibility() == View.GONE
|
||||
? 0
|
||||
: mNotificationShelfController.getIntrinsicHeight() + notificationPadding;
|
||||
: mNotificationShelfController.getIntrinsicHeight();
|
||||
|
||||
// Padding to add to the bottom of the stack to keep a minimum distance from the top of
|
||||
// the lock icon.
|
||||
@@ -1493,13 +1487,11 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
float availableSpace =
|
||||
mNotificationStackScrollLayoutController.getHeight()
|
||||
- topPadding
|
||||
- shelfHeight
|
||||
- bottomPadding;
|
||||
mKeyguardNotificationAvailableSpace = availableSpace;
|
||||
|
||||
return mNotificationStackSizeCalculator.computeMaxKeyguardNotifications(
|
||||
mNotificationStackScrollLayoutController.getView(), availableSpace,
|
||||
shelfHeight);
|
||||
shelfIntrinsicHeight);
|
||||
}
|
||||
|
||||
private void updateClock() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.stack
|
||||
|
||||
import android.annotation.DimenRes
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.View.VISIBLE
|
||||
@@ -27,6 +28,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.mockito.nullable
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
@@ -34,8 +36,8 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@@ -49,17 +51,15 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var sizeCalculator: NotificationStackSizeCalculator
|
||||
|
||||
private val gapHeight = px(R.dimen.notification_section_divider_height)
|
||||
private val dividerHeight = px(R.dimen.notification_divider_height)
|
||||
private val shelfHeight = px(R.dimen.notification_shelf_height)
|
||||
private val rowHeight = px(R.dimen.notification_max_height)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any()))
|
||||
.thenReturn(GAP_HEIGHT)
|
||||
with(testableResources) {
|
||||
addOverride(R.integer.keyguard_max_notification_count, -1)
|
||||
addOverride(R.dimen.notification_divider_height, DIVIDER_HEIGHT.toInt())
|
||||
}
|
||||
|
||||
sizeCalculator =
|
||||
NotificationStackSizeCalculator(
|
||||
statusBarStateController = sysuiStatusBarStateController,
|
||||
@@ -68,7 +68,7 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun computeMaxKeyguardNotifications_zeroSpace_returnZero() {
|
||||
val rows = listOf(createMockRow(height = ROW_HEIGHT))
|
||||
val rows = listOf(createMockRow(height = rowHeight))
|
||||
|
||||
val maxNotifications =
|
||||
computeMaxKeyguardNotifications(rows, availableSpace = 0f, shelfHeight = 0f)
|
||||
@@ -87,105 +87,78 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun computeMaxKeyguardNotifications_spaceForOne_returnsOne() {
|
||||
val rowHeight = ROW_HEIGHT
|
||||
val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
|
||||
val shelfHeight =
|
||||
totalSpaceForEachRow / 2 // In this way shelf absence will not leave room for another.
|
||||
val spaceForOne = totalSpaceForEachRow
|
||||
val rows =
|
||||
listOf(
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight))
|
||||
fun computeMaxKeyguardNotifications_spaceForOneAndShelf_returnsOne() {
|
||||
setGapHeight(gapHeight)
|
||||
val shelfHeight = rowHeight / 2 // Shelf absence won't leave room for another row.
|
||||
val availableSpace =
|
||||
listOf(rowHeight + dividerHeight, gapHeight + dividerHeight + shelfHeight).sum()
|
||||
val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
|
||||
|
||||
val maxNotifications =
|
||||
computeMaxKeyguardNotifications(
|
||||
rows, availableSpace = spaceForOne, shelfHeight = shelfHeight)
|
||||
|
||||
assertThat(maxNotifications).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun computeMaxKeyguardNotifications_spaceForOne_shelfUsableForLastNotification_returnsTwo() {
|
||||
val rowHeight = ROW_HEIGHT
|
||||
val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
|
||||
val shelfHeight = totalSpaceForEachRow + DIVIDER_HEIGHT
|
||||
val spaceForOne = totalSpaceForEachRow
|
||||
val rows =
|
||||
listOf(
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight))
|
||||
|
||||
val maxNotifications =
|
||||
computeMaxKeyguardNotifications(
|
||||
rows, availableSpace = spaceForOne, shelfHeight = shelfHeight)
|
||||
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
|
||||
|
||||
assertThat(maxNotifications).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun computeMaxKeyguardNotifications_spaceForTwo_returnsTwo() {
|
||||
val rowHeight = ROW_HEIGHT
|
||||
val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
|
||||
val spaceForTwo = totalSpaceForEachRow * 2 + DIVIDER_HEIGHT
|
||||
val rows =
|
||||
setGapHeight(gapHeight)
|
||||
val shelfHeight = shelfHeight + dividerHeight
|
||||
val availableSpace =
|
||||
listOf(
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight))
|
||||
rowHeight + dividerHeight,
|
||||
gapHeight + rowHeight + dividerHeight,
|
||||
gapHeight + dividerHeight + shelfHeight)
|
||||
.sum()
|
||||
val rows =
|
||||
listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))
|
||||
|
||||
val maxNotifications = computeMaxKeyguardNotifications(rows, spaceForTwo, shelfHeight = 0f)
|
||||
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
|
||||
|
||||
assertThat(maxNotifications).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun computeHeight_returnsAtMostSpaceAvailable_withGapBeforeShelf() {
|
||||
val rowHeight = ROW_HEIGHT
|
||||
val shelfHeight = SHELF_HEIGHT
|
||||
val totalSpaceForEachRow = GAP_HEIGHT + rowHeight + DIVIDER_HEIGHT
|
||||
val availableSpace = totalSpaceForEachRow * 2
|
||||
setGapHeight(gapHeight)
|
||||
val shelfHeight = shelfHeight
|
||||
val availableSpace =
|
||||
listOf(
|
||||
rowHeight + dividerHeight,
|
||||
gapHeight + rowHeight + dividerHeight,
|
||||
gapHeight + dividerHeight + shelfHeight)
|
||||
.sum()
|
||||
|
||||
// All rows in separate sections (default setup).
|
||||
val rows =
|
||||
listOf(
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight))
|
||||
listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))
|
||||
|
||||
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
|
||||
assertThat(maxNotifications).isEqualTo(2)
|
||||
|
||||
val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, SHELF_HEIGHT)
|
||||
assertThat(height).isAtMost(availableSpace + GAP_HEIGHT + SHELF_HEIGHT)
|
||||
val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
|
||||
assertThat(height).isAtMost(availableSpace)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun computeHeight_returnsAtMostSpaceAvailable_noGapBeforeShelf() {
|
||||
val rowHeight = ROW_HEIGHT
|
||||
val shelfHeight = SHELF_HEIGHT
|
||||
val totalSpaceForEachRow = GAP_HEIGHT + rowHeight + DIVIDER_HEIGHT
|
||||
val availableSpace = totalSpaceForEachRow * 1
|
||||
|
||||
fun computeHeight_noGapBeforeShelf_returnsAtMostSpaceAvailable() {
|
||||
// Both rows are in the same section.
|
||||
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any()))
|
||||
.thenReturn(0f)
|
||||
val rows =
|
||||
listOf(
|
||||
createMockRow(rowHeight),
|
||||
createMockRow(rowHeight))
|
||||
setGapHeight(0f)
|
||||
val rowHeight = rowHeight
|
||||
val shelfHeight = shelfHeight
|
||||
val availableSpace = listOf(rowHeight + dividerHeight, dividerHeight + shelfHeight).sum()
|
||||
val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
|
||||
|
||||
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
|
||||
assertThat(maxNotifications).isEqualTo(1)
|
||||
|
||||
val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, SHELF_HEIGHT)
|
||||
assertThat(height).isAtMost(availableSpace + SHELF_HEIGHT)
|
||||
val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
|
||||
assertThat(height).isAtMost(availableSpace)
|
||||
}
|
||||
|
||||
private fun computeMaxKeyguardNotifications(
|
||||
rows: List<ExpandableView>,
|
||||
availableSpace: Float,
|
||||
shelfHeight: Float = SHELF_HEIGHT
|
||||
shelfHeight: Float = this.shelfHeight
|
||||
): Int {
|
||||
setupChildren(rows)
|
||||
return sizeCalculator.computeMaxKeyguardNotifications(
|
||||
@@ -204,9 +177,9 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
|
||||
(1..number).map { createMockRow() }.toList()
|
||||
|
||||
private fun createMockRow(
|
||||
height: Float = ROW_HEIGHT,
|
||||
height: Float = rowHeight,
|
||||
isRemoved: Boolean = false,
|
||||
visibility: Int = VISIBLE,
|
||||
visibility: Int = VISIBLE
|
||||
): ExpandableNotificationRow {
|
||||
val row = mock(ExpandableNotificationRow::class.java)
|
||||
val entry = mock(NotificationEntry::class.java)
|
||||
@@ -220,11 +193,12 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
|
||||
return row
|
||||
}
|
||||
|
||||
/** Default dimensions for tests that don't overwrite them. */
|
||||
companion object {
|
||||
const val GAP_HEIGHT = 12f
|
||||
const val DIVIDER_HEIGHT = 3f
|
||||
const val SHELF_HEIGHT = 14f
|
||||
const val ROW_HEIGHT = SHELF_HEIGHT * 3
|
||||
private fun setGapHeight(height: Float) {
|
||||
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any())).thenReturn(height)
|
||||
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), /* visibleIndex= */ eq(0)))
|
||||
.thenReturn(0f)
|
||||
}
|
||||
|
||||
private fun px(@DimenRes id: Int): Float =
|
||||
testableResources.resources.getDimensionPixelSize(id).toFloat()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user