Merge "Increase vertical overlap between notification shelf and lock icon" into tm-dev

This commit is contained in:
Julia Reynolds
2022-06-06 15:21:46 +00:00
committed by Android (Google) Code Review
5 changed files with 302 additions and 106 deletions

View File

@@ -386,7 +386,7 @@
<dimen name="split_shade_notifications_scrim_margin_bottom">0dp</dimen> <dimen name="split_shade_notifications_scrim_margin_bottom">0dp</dimen>
<dimen name="shelf_and_lock_icon_overlap">5dp</dimen> <dimen name="shelf_and_lock_icon_overlap">@dimen/notification_shelf_height</dimen>
<dimen name="notification_panel_margin_horizontal">0dp</dimen> <dimen name="notification_panel_margin_horizontal">0dp</dimen>

View File

@@ -39,7 +39,11 @@ private const val TAG = "NotifStackSizeCalc"
private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG) private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG)
private val SPEW = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE) private val SPEW = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE)
/** Calculates number of notifications to display and the height of the notification stack. */ /**
* Calculates number of notifications to display and the height of the notification stack.
* "Notifications" refers to any ExpandableView that we show on lockscreen, which can include the
* media player.
*/
@SysUISingleton @SysUISingleton
class NotificationStackSizeCalculator class NotificationStackSizeCalculator
@Inject @Inject
@@ -65,21 +69,60 @@ constructor(
} }
/** /**
* Given the [totalAvailableSpace] constraint, calculates how many notification to show. * Returns whether notifications and (shelf if visible) can fit in total space available.
* * [spaceForShelf] is extra vertical space allowed for the shelf to overlap the lock icon.
* This number is only valid in keyguard. */
private fun canStackFitInSpace(
stackHeight: StackHeight,
spaceForNotifications: Float,
spaceForShelf: Float,
): Boolean {
val (notificationsHeight, shelfHeightWithSpaceBefore) = stackHeight
var canFit: Boolean
if (shelfHeightWithSpaceBefore == 0f) {
canFit = notificationsHeight <= spaceForNotifications
log {
"canStackFitInSpace[$canFit] = notificationsHeight[$notificationsHeight]" +
" <= spaceForNotifications[$spaceForNotifications]"
}
} else {
canFit =
(notificationsHeight + shelfHeightWithSpaceBefore) <=
(spaceForNotifications + spaceForShelf)
log {
"canStackFitInSpace[$canFit] = (notificationsHeight[$notificationsHeight]" +
" + shelfHeightWithSpaceBefore[$shelfHeightWithSpaceBefore])" +
" <= (spaceForNotifications[$spaceForNotifications] " +
" + spaceForShelf[$spaceForShelf])"
}
}
return canFit
}
/**
* Given the [spaceForNotifications] and [spaceForShelf] constraints, calculate how many
* notifications to show. This number is only valid in keyguard.
* *
* @param totalAvailableSpace space for notifications. This includes the space for the shelf. * @param totalAvailableSpace space for notifications. This includes the space for the shelf.
*/ */
fun computeMaxKeyguardNotifications( fun computeMaxKeyguardNotifications(
stack: NotificationStackScrollLayout, stack: NotificationStackScrollLayout,
totalAvailableSpace: Float, spaceForNotifications: Float,
spaceForShelf: Float,
shelfIntrinsicHeight: Float shelfIntrinsicHeight: Float
): Int { ): Int {
log { "\n" }
val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight) val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
var maxNotifications = var maxNotifications =
stackHeightSequence.lastIndexWhile { stackHeight -> stackHeight <= totalAvailableSpace } stackHeightSequence.lastIndexWhile { heightResult ->
canStackFitInSpace(
heightResult,
spaceForNotifications = spaceForNotifications,
spaceForShelf = spaceForShelf)
}
if (onLockscreen()) { if (onLockscreen()) {
maxNotifications = min(maxKeyguardNotifications, maxNotifications) maxNotifications = min(maxKeyguardNotifications, maxNotifications)
@@ -90,7 +133,8 @@ constructor(
log { log {
val sequence = if (SPEW) " stackHeightSequence=${stackHeightSequence.toList()}" else "" val sequence = if (SPEW) " stackHeightSequence=${stackHeightSequence.toList()}" else ""
"computeMaxKeyguardNotifications(" + "computeMaxKeyguardNotifications(" +
"availableSpace=$totalAvailableSpace" + " spaceForNotifications=$spaceForNotifications" +
" spaceForShelf=$spaceForShelf" +
" shelfHeight=$shelfIntrinsicHeight) -> $maxNotifications$sequence" " shelfHeight=$shelfIntrinsicHeight) -> $maxNotifications$sequence"
} }
return maxNotifications return maxNotifications
@@ -112,33 +156,51 @@ constructor(
maxNotifications: Int, maxNotifications: Int,
shelfIntrinsicHeight: Float shelfIntrinsicHeight: Float
): Float { ): Float {
log { "\n" }
val heightPerMaxNotifications = val heightPerMaxNotifications =
computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight) computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
val height =
val (notificationsHeight, shelfHeightWithSpaceBefore) =
heightPerMaxNotifications.elementAtOrElse(maxNotifications) { heightPerMaxNotifications.elementAtOrElse(maxNotifications) {
heightPerMaxNotifications.last() // Height with all notifications visible. heightPerMaxNotifications.last() // Height with all notifications visible.
} }
log { "computeHeight(maxNotifications=$maxNotifications) -> $height" } log {
return height "computeHeight(maxNotifications=$maxNotifications," +
"shelfIntrinsicHeight=$shelfIntrinsicHeight) -> " +
"${notificationsHeight + shelfHeightWithSpaceBefore}" +
" = ($notificationsHeight + $shelfHeightWithSpaceBefore)"
}
return notificationsHeight + shelfHeightWithSpaceBefore
} }
/** The ith result in the sequence is the height with ith max notifications. */ private data class StackHeight(
// Float height with ith max notifications (not including shelf)
val notificationsHeight: Float,
// Float height of shelf (0 if shelf is not showing), and space before the shelf that
// changes during the lockscreen <=> full shade transition.
val shelfHeightWithSpaceBefore: Float
)
private fun computeHeightPerNotificationLimit( private fun computeHeightPerNotificationLimit(
stack: NotificationStackScrollLayout, stack: NotificationStackScrollLayout,
shelfIntrinsicHeight: Float shelfHeight: Float
): Sequence<Float> = sequence { ): Sequence<StackHeight> = sequence {
log { "computeHeightPerNotificationLimit" }
val children = stack.showableChildren().toList() val children = stack.showableChildren().toList()
var height = 0f var notifications = 0f
var previous: ExpandableView? = null var previous: ExpandableView? = null
val onLockscreen = onLockscreen() val onLockscreen = onLockscreen()
yield(dividerHeight + shelfIntrinsicHeight) // Only shelf. // Only shelf. This should never happen, since we allow 1 view minimum (EmptyViewState).
yield(StackHeight(notificationsHeight = 0f, shelfHeightWithSpaceBefore = shelfHeight))
children.forEachIndexed { i, currentNotification -> children.forEachIndexed { i, currentNotification ->
height += spaceNeeded(currentNotification, i, previous, stack, onLockscreen) notifications += spaceNeeded(currentNotification, i, previous, stack, onLockscreen)
previous = currentNotification previous = currentNotification
val shelfHeight = val shelfWithSpaceBefore =
if (i == children.lastIndex) { if (i == children.lastIndex) {
0f // No shelf needed. 0f // No shelf needed.
} else { } else {
@@ -149,10 +211,16 @@ constructor(
previous = currentNotification, previous = currentNotification,
current = children[firstViewInShelfIndex], current = children[firstViewInShelfIndex],
currentIndex = firstViewInShelfIndex) currentIndex = firstViewInShelfIndex)
spaceBeforeShelf + shelfIntrinsicHeight spaceBeforeShelf + shelfHeight
} }
log {
yield(height + shelfHeight) "i=$i notificationsHeight=$notifications " +
"shelfHeightWithSpaceBefore=$shelfWithSpaceBefore"
}
yield(
StackHeight(
notificationsHeight = notifications,
shelfHeightWithSpaceBefore = shelfWithSpaceBefore))
} }
} }

View File

@@ -1520,50 +1520,77 @@ public class NotificationPanelViewController extends PanelViewController {
return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight; return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight;
} }
/** /** Returns space between top of lock icon and bottom of NotificationStackScrollLayout. */
* @return Space available to show notifications on lockscreen. private float getLockIconPadding() {
*/ float lockIconPadding = 0f;
if (mLockIconViewController.getTop() != 0f) {
lockIconPadding = mNotificationStackScrollLayoutController.getBottom()
- mLockIconViewController.getTop();
}
return lockIconPadding;
}
/** Returns space available to show notifications on lockscreen. */
@VisibleForTesting @VisibleForTesting
float getSpaceForLockscreenNotifications() { float getVerticalSpaceForLockscreenNotifications() {
final float lockIconPadding = getLockIconPadding();
float bottomPadding = Math.max(lockIconPadding,
Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding));
mKeyguardNotificationBottomPadding = bottomPadding;
float staticTopPadding = mClockPositionAlgorithm.getLockscreenMinStackScrollerPadding() float staticTopPadding = mClockPositionAlgorithm.getLockscreenMinStackScrollerPadding()
// getMinStackScrollerPadding is from the top of the screen, // getMinStackScrollerPadding is from the top of the screen,
// but we need it from the top of the NSSL. // but we need it from the top of the NSSL.
- mNotificationStackScrollLayoutController.getTop(); - mNotificationStackScrollLayoutController.getTop();
// Space between bottom of notifications and top of lock icon or udfps background.
float lockIconPadding = mLockIconViewController.getTop();
if (mLockIconViewController.getTop() != 0) {
lockIconPadding = mNotificationStackScrollLayoutController.getBottom()
- mLockIconViewController.getTop()
- mShelfAndLockIconOverlap;
}
float bottomPadding = Math.max(lockIconPadding,
Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding));
mKeyguardNotificationBottomPadding = bottomPadding;
mKeyguardNotificationTopPadding = staticTopPadding; mKeyguardNotificationTopPadding = staticTopPadding;
// To debug the available space, enable debug lines in this class. If you change how the // To debug the available space, enable debug lines in this class. If you change how the
// available space is calculated, please also update those lines. // available space is calculated, please also update those lines.
float availableSpace = final float verticalSpace =
mNotificationStackScrollLayoutController.getHeight() mNotificationStackScrollLayoutController.getHeight()
- staticTopPadding - staticTopPadding
- bottomPadding; - bottomPadding;
if (SPEW_LOGCAT) { if (SPEW_LOGCAT) {
Log.d(TAG, "getSpaceForLockscreenNotifications()" Log.i(TAG, "\n");
+ " availableSpace=" + availableSpace Log.i(TAG, "staticTopPadding[" + staticTopPadding
+ " NSSL.height=" + mNotificationStackScrollLayoutController.getHeight() + "] = Clock.padding["
+ " NSSL.top=" + mNotificationStackScrollLayoutController.getTop() + mClockPositionAlgorithm.getLockscreenMinStackScrollerPadding()
+ " staticTopPadding=" + staticTopPadding + "] - NSSLC.top[" + mNotificationStackScrollLayoutController.getTop()
+ " bottomPadding=" + bottomPadding + "]"
+ " lockIconPadding=" + lockIconPadding );
+ " mIndicationBottomPadding=" + mIndicationBottomPadding Log.i(TAG, "bottomPadding[" + bottomPadding
+ " mAmbientIndicationBottomPadding=" + mAmbientIndicationBottomPadding + "] = max(ambientIndicationBottomPadding[" + mAmbientIndicationBottomPadding
+ "], mIndicationBottomPadding[" + mIndicationBottomPadding
+ "], lockIconPadding[" + lockIconPadding
+ "])"
);
Log.i(TAG, "verticalSpaceForNotifications[" + verticalSpace
+ "] = NSSL.height[" + mNotificationStackScrollLayoutController.getHeight()
+ "] - staticTopPadding[" + staticTopPadding
+ "] - bottomPadding[" + bottomPadding
+ "]"
); );
} }
return availableSpace; return verticalSpace;
}
/** Returns extra space available to show the shelf on lockscreen */
@VisibleForTesting
float getVerticalSpaceForLockscreenShelf() {
final float lockIconPadding = getLockIconPadding();
final float noShelfOverlapBottomPadding =
Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
final float extraSpaceForShelf = lockIconPadding - noShelfOverlapBottomPadding;
if (extraSpaceForShelf > 0f) {
return Math.min(mNotificationShelfController.getIntrinsicHeight(),
extraSpaceForShelf);
}
return 0f;
} }
/** /**
@@ -1579,16 +1606,12 @@ public class NotificationPanelViewController extends PanelViewController {
} }
return mMaxAllowedKeyguardNotifications; return mMaxAllowedKeyguardNotifications;
} }
final float shelfIntrinsicHeight =
mNotificationShelfController.getVisibility() == View.GONE
? 0
: mNotificationShelfController.getIntrinsicHeight();
return mNotificationStackSizeCalculator.computeMaxKeyguardNotifications( return mNotificationStackSizeCalculator.computeMaxKeyguardNotifications(
mNotificationStackScrollLayoutController.getView(), mNotificationStackScrollLayoutController.getView(),
getSpaceForLockscreenNotifications(), getVerticalSpaceForLockscreenNotifications(),
shelfIntrinsicHeight); getVerticalSpaceForLockscreenShelf(),
mNotificationShelfController.getIntrinsicHeight()
);
} }
private void updateClock() { private void updateClock() {
@@ -3812,7 +3835,7 @@ public class NotificationPanelViewController extends PanelViewController {
public void setAmbientIndicationTop(int ambientIndicationTop, boolean ambientTextVisible) { public void setAmbientIndicationTop(int ambientIndicationTop, boolean ambientTextVisible) {
int ambientIndicationBottomPadding = 0; int ambientIndicationBottomPadding = 0;
if (ambientTextVisible) { if (ambientTextVisible) {
int stackBottom = mNotificationStackScrollLayoutController.getView().getBottom(); int stackBottom = mNotificationStackScrollLayoutController.getBottom();
ambientIndicationBottomPadding = stackBottom - ambientIndicationTop; ambientIndicationBottomPadding = stackBottom - ambientIndicationTop;
} }
if (mAmbientIndicationBottomPadding != ambientIndicationBottomPadding) { if (mAmbientIndicationBottomPadding != ambientIndicationBottomPadding) {

View File

@@ -46,7 +46,8 @@ import org.mockito.MockitoAnnotations
class NotificationStackSizeCalculatorTest : SysuiTestCase() { class NotificationStackSizeCalculatorTest : SysuiTestCase() {
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController @Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@Mock private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController @Mock
private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
@Mock private lateinit var stackLayout: NotificationStackScrollLayout @Mock private lateinit var stackLayout: NotificationStackScrollLayout
private val testableResources = mContext.orCreateTestableResources private val testableResources = mContext.orCreateTestableResources
@@ -74,7 +75,8 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
val rows = listOf(createMockRow(height = rowHeight)) val rows = listOf(createMockRow(height = rowHeight))
val maxNotifications = val maxNotifications =
computeMaxKeyguardNotifications(rows, availableSpace = 0f, shelfHeight = 0f) computeMaxKeyguardNotifications(
rows, spaceForNotifications = 0f, spaceForShelf = 0f, shelfHeight = 0f)
assertThat(maxNotifications).isEqualTo(0) assertThat(maxNotifications).isEqualTo(0)
} }
@@ -84,7 +86,12 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
val numberOfRows = 30 val numberOfRows = 30
val rows = createLockscreenRows(numberOfRows) val rows = createLockscreenRows(numberOfRows)
val maxNotifications = computeMaxKeyguardNotifications(rows, Float.MAX_VALUE) val maxNotifications =
computeMaxKeyguardNotifications(
rows,
spaceForNotifications = Float.MAX_VALUE,
spaceForShelf = Float.MAX_VALUE,
shelfHeight)
assertThat(maxNotifications).isEqualTo(numberOfRows) assertThat(maxNotifications).isEqualTo(numberOfRows)
} }
@@ -93,11 +100,12 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
fun computeMaxKeyguardNotifications_spaceForOneAndShelf_returnsOne() { fun computeMaxKeyguardNotifications_spaceForOneAndShelf_returnsOne() {
setGapHeight(gapHeight) setGapHeight(gapHeight)
val shelfHeight = rowHeight / 2 // Shelf absence won't leave room for another row. val shelfHeight = rowHeight / 2 // Shelf absence won't leave room for another row.
val availableSpace = val spaceForNotifications = rowHeight + dividerHeight
listOf(rowHeight + dividerHeight, gapHeight + dividerHeight + shelfHeight).sum() val spaceForShelf = gapHeight + dividerHeight + shelfHeight
val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight)) val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight) val maxNotifications =
computeMaxKeyguardNotifications(rows, spaceForNotifications, spaceForShelf, shelfHeight)
assertThat(maxNotifications).isEqualTo(1) assertThat(maxNotifications).isEqualTo(1)
} }
@@ -106,16 +114,19 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
fun computeMaxKeyguardNotifications_spaceForTwo_returnsTwo() { fun computeMaxKeyguardNotifications_spaceForTwo_returnsTwo() {
setGapHeight(gapHeight) setGapHeight(gapHeight)
val shelfHeight = shelfHeight + dividerHeight val shelfHeight = shelfHeight + dividerHeight
val availableSpace = val spaceForNotifications =
listOf( listOf(
rowHeight + dividerHeight, rowHeight + dividerHeight,
gapHeight + rowHeight + dividerHeight, gapHeight + rowHeight + dividerHeight,
gapHeight + dividerHeight + shelfHeight) )
.sum() .sum()
val spaceForShelf = gapHeight + dividerHeight + shelfHeight
val rows = val rows =
listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight)) listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight) val maxNotifications =
computeMaxKeyguardNotifications(
rows, spaceForNotifications + 1, spaceForShelf, shelfHeight)
assertThat(maxNotifications).isEqualTo(2) assertThat(maxNotifications).isEqualTo(2)
} }
@@ -124,19 +135,25 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
fun computeHeight_gapBeforeShelf_returnsSpaceUsed() { fun computeHeight_gapBeforeShelf_returnsSpaceUsed() {
// Each row in separate section. // Each row in separate section.
setGapHeight(gapHeight) setGapHeight(gapHeight)
val spaceUsed =
listOf(rowHeight, val spaceForNotifications =
listOf(
rowHeight,
dividerHeight + gapHeight + rowHeight, dividerHeight + gapHeight + rowHeight,
dividerHeight + gapHeight + shelfHeight) )
.sum() .sum()
val availableSpace = spaceUsed + 1;
val spaceForShelf = dividerHeight + gapHeight + shelfHeight
val spaceUsed = spaceForNotifications + spaceForShelf
val rows = val rows =
listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight)) listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight) val maxNotifications =
computeMaxKeyguardNotifications(rows, spaceForNotifications, spaceForShelf, shelfHeight)
assertThat(maxNotifications).isEqualTo(2) assertThat(maxNotifications).isEqualTo(2)
val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight) val height =
sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
assertThat(height).isEqualTo(spaceUsed) assertThat(height).isEqualTo(spaceUsed)
} }
@@ -145,19 +162,19 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
// Both rows are in the same section. // Both rows are in the same section.
setGapHeight(0f) setGapHeight(0f)
val rowHeight = rowHeight val spaceForNotifications = rowHeight
val shelfHeight = shelfHeight val spaceForShelf = dividerHeight + shelfHeight
val spaceUsed = val spaceUsed = spaceForNotifications + spaceForShelf
listOf(rowHeight,
dividerHeight + shelfHeight)
.sum()
val availableSpace = spaceUsed + 1
val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight)) val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight) // test that we only use space required
val maxNotifications =
computeMaxKeyguardNotifications(
rows, spaceForNotifications + 1, spaceForShelf, shelfHeight)
assertThat(maxNotifications).isEqualTo(1) assertThat(maxNotifications).isEqualTo(1)
val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight) val height =
sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
assertThat(height).isEqualTo(spaceUsed) assertThat(height).isEqualTo(spaceUsed)
} }
@@ -191,8 +208,13 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
whenever(expandableView.getMinHeight(any())).thenReturn(5) whenever(expandableView.getMinHeight(any())).thenReturn(5)
whenever(expandableView.intrinsicHeight).thenReturn(10) whenever(expandableView.intrinsicHeight).thenReturn(10)
val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0, val space =
previousView = null, stack = stackLayout, onLockscreen = true) sizeCalculator.spaceNeeded(
expandableView,
visibleIndex = 0,
previousView = null,
stack = stackLayout,
onLockscreen = true)
assertThat(space).isEqualTo(5) assertThat(space).isEqualTo(5)
} }
@@ -205,19 +227,25 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
whenever(expandableView.getMinHeight(any())).thenReturn(5) whenever(expandableView.getMinHeight(any())).thenReturn(5)
whenever(expandableView.intrinsicHeight).thenReturn(10) whenever(expandableView.intrinsicHeight).thenReturn(10)
val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0, val space =
previousView = null, stack = stackLayout, onLockscreen = false) sizeCalculator.spaceNeeded(
expandableView,
visibleIndex = 0,
previousView = null,
stack = stackLayout,
onLockscreen = false)
assertThat(space).isEqualTo(10) assertThat(space).isEqualTo(10)
} }
private fun computeMaxKeyguardNotifications( private fun computeMaxKeyguardNotifications(
rows: List<ExpandableView>, rows: List<ExpandableView>,
availableSpace: Float, spaceForNotifications: Float,
spaceForShelf: Float,
shelfHeight: Float = this.shelfHeight shelfHeight: Float = this.shelfHeight
): Int { ): Int {
setupChildren(rows) setupChildren(rows)
return sizeCalculator.computeMaxKeyguardNotifications( return sizeCalculator.computeMaxKeyguardNotifications(
stackLayout, availableSpace, shelfHeight) stackLayout, spaceForNotifications, spaceForShelf, shelfHeight)
} }
private fun setupChildren(children: List<ExpandableView>) { private fun setupChildren(children: List<ExpandableView>) {

View File

@@ -583,7 +583,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
listener.onHeightChanged(mock(ExpandableView.class), false); listener.onHeightChanged(mock(ExpandableView.class), false);
verify(mNotificationStackSizeCalculator) verify(mNotificationStackSizeCalculator)
.computeMaxKeyguardNotifications(any(), anyFloat(), anyFloat()); .computeMaxKeyguardNotifications(any(), anyFloat(), anyFloat(), anyFloat());
} }
@Test @Test
@@ -599,7 +599,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
listener.onHeightChanged(mock(ExpandableView.class), false); listener.onHeightChanged(mock(ExpandableView.class), false);
verify(mNotificationStackSizeCalculator, never()) verify(mNotificationStackSizeCalculator, never())
.computeMaxKeyguardNotifications(any(), anyFloat(), anyFloat()); .computeMaxKeyguardNotifications(any(), anyFloat(), anyFloat(), anyFloat());
} }
@Test @Test
@@ -622,25 +622,102 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
.isNotEqualTo(-1); .isNotEqualTo(-1);
} }
@Test private void setBottomPadding(int stackBottom, int lockIconPadding, int indicationPadding,
public void getLockscreenSpaceForNotifications_includesOverlapWithLockIcon() { int ambientPadding) {
when(mResources.getDimensionPixelSize(R.dimen.keyguard_indication_bottom_padding))
.thenReturn(0);
mNotificationPanelViewController.setAmbientIndicationTop(
/* ambientIndicationTop= */ 0, /* ambientTextVisible */ false);
// Use lock icon padding (100 - 80 - 5 = 15) as bottom padding
when(mNotificationStackScrollLayoutController.getBottom()).thenReturn(100);
when(mLockIconViewController.getTop()).thenReturn(80f);
when(mResources.getDimensionPixelSize(R.dimen.shelf_and_lock_icon_overlap)).thenReturn(5);
// Available space (100 - 0 - 15 = 85)
when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(100);
when(mNotificationStackScrollLayoutController.getTop()).thenReturn(0); when(mNotificationStackScrollLayoutController.getTop()).thenReturn(0);
mNotificationPanelViewController.updateResources(); when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(stackBottom);
when(mNotificationStackScrollLayoutController.getBottom()).thenReturn(stackBottom);
when(mLockIconViewController.getTop()).thenReturn((float) (stackBottom - lockIconPadding));
assertThat(mNotificationPanelViewController.getSpaceForLockscreenNotifications()) when(mResources.getDimensionPixelSize(R.dimen.keyguard_indication_bottom_padding))
.isEqualTo(85); .thenReturn(indicationPadding);
mNotificationPanelViewController.loadDimens();
mNotificationPanelViewController.setAmbientIndicationTop(
/* ambientIndicationTop= */ stackBottom - ambientPadding,
/* ambientTextVisible= */ true);
}
@Test
public void getVerticalSpaceForLockscreenNotifications_useLockIconBottomPadding_returnsSpaceAvailable() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 20,
/* indicationPadding= */ 0,
/* ambientPadding= */ 0);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenNotifications())
.isEqualTo(80);
}
@Test
public void getVerticalSpaceForLockscreenNotifications_useIndicationBottomPadding_returnsSpaceAvailable() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 0,
/* indicationPadding= */ 30,
/* ambientPadding= */ 0);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenNotifications())
.isEqualTo(70);
}
@Test
public void getVerticalSpaceForLockscreenNotifications_useAmbientBottomPadding_returnsSpaceAvailable() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 0,
/* indicationPadding= */ 0,
/* ambientPadding= */ 40);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenNotifications())
.isEqualTo(60);
}
@Test
public void getVerticalSpaceForLockscreenShelf_useLockIconBottomPadding_returnsShelfHeight() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 20,
/* indicationPadding= */ 0,
/* ambientPadding= */ 0);
when(mNotificationShelfController.getIntrinsicHeight()).thenReturn(5);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf())
.isEqualTo(5);
}
@Test
public void getVerticalSpaceForLockscreenShelf_useIndicationBottomPadding_returnsZero() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 0,
/* indicationPadding= */ 30,
/* ambientPadding= */ 0);
when(mNotificationShelfController.getIntrinsicHeight()).thenReturn(5);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf())
.isEqualTo(0);
}
@Test
public void getVerticalSpaceForLockscreenShelf_useAmbientBottomPadding_returnsZero() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 0,
/* indicationPadding= */ 0,
/* ambientPadding= */ 40);
when(mNotificationShelfController.getIntrinsicHeight()).thenReturn(5);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf())
.isEqualTo(0);
}
@Test
public void getVerticalSpaceForLockscreenShelf_useLockIconPadding_returnsLessThanShelfHeight() {
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 10,
/* indicationPadding= */ 8,
/* ambientPadding= */ 0);
when(mNotificationShelfController.getIntrinsicHeight()).thenReturn(5);
assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf())
.isEqualTo(2);
} }
@Test @Test