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