Merge "Show HUN layout on lockscreen when FSI permission is denied" into udc-dev

This commit is contained in:
Lyn Han
2023-03-10 19:13:35 +00:00
committed by Android (Google) Code Review
6 changed files with 127 additions and 4 deletions

View File

@@ -2622,7 +2622,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
* except for legacy use cases.
*/
public boolean canShowHeadsUp() {
if (mOnKeyguard && !isDozing() && !isBypassEnabled()) {
if (mOnKeyguard && !isDozing() && !isBypassEnabled() && !mEntry.isStickyAndNotDemoted()) {
return false;
}
return true;

View File

@@ -264,12 +264,18 @@ constructor(
onLockscreen: Boolean
): Float {
assert(view.isShowable(onLockscreen))
var size =
if (onLockscreen) {
view.getMinHeight(/* ignoreTemporaryStates= */ true).toFloat()
if (view is ExpandableNotificationRow && view.entry.isStickyAndNotDemoted) {
view.intrinsicHeight.toFloat()
} else {
view.getMinHeight(/* ignoreTemporaryStates= */ true).toFloat()
}
} else {
view.intrinsicHeight.toFloat()
}
size += calculateGapAndDividerHeight(stack, previousView, current = view, visibleIndex)
return size
}

View File

@@ -763,7 +763,7 @@ public class StackScrollAlgorithm {
float unmodifiedEndLocation = childState.getYTranslation() + childState.height;
if (mIsExpanded) {
if (row.mustStayOnScreen() && !childState.headsUpIsVisible
&& !row.showingPulsing()) {
&& !row.showingPulsing() && !ambientState.isOnKeyguard()) {
// Ensure that the heads up is always visible even when scrolled off
clampHunToTop(mQuickQsOffsetHeight, ambientState.getStackTranslation(),
row.getCollapsedHeight(), childState);

View File

@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import org.junit.Assert;
import org.junit.Before;
@@ -104,6 +105,61 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
mNotificationTestHelper.setFeatureFlags(fakeFeatureFlags);
}
@Test
public void testCanShowHeadsUp_notOnKeyguard_true() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createRow();
row.setOnKeyguard(false);
assertTrue(row.canShowHeadsUp());
}
@Test
public void testCanShowHeadsUp_dozing_true() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createRow();
StatusBarStateController statusBarStateControllerMock =
mNotificationTestHelper.getStatusBarStateController();
when(statusBarStateControllerMock.isDozing()).thenReturn(true);
assertTrue(row.canShowHeadsUp());
}
@Test
public void testCanShowHeadsUp_bypassEnabled_true() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createRow();
KeyguardBypassController keyguardBypassControllerMock =
mNotificationTestHelper.getKeyguardBypassController();
when(keyguardBypassControllerMock.getBypassEnabled()).thenReturn(true);
assertTrue(row.canShowHeadsUp());
}
@Test
public void testCanShowHeadsUp_stickyAndNotDemoted_true() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createStickyRow();
assertTrue(row.canShowHeadsUp());
}
@Test
public void testCanShowHeadsUp_false() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createRow();
row.setOnKeyguard(true);
StatusBarStateController statusBarStateControllerMock =
mNotificationTestHelper.getStatusBarStateController();
when(statusBarStateControllerMock.isDozing()).thenReturn(false);
KeyguardBypassController keyguardBypassControllerMock =
mNotificationTestHelper.getKeyguardBypassController();
when(keyguardBypassControllerMock.getBypassEnabled()).thenReturn(false);
assertFalse(row.canShowHeadsUp());
}
@Test
public void testUpdateBackgroundColors_isRecursive() throws Exception {
ExpandableNotificationRow group = mNotificationTestHelper.createGroup();

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
@@ -74,6 +75,7 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
@@ -121,6 +123,7 @@ public class NotificationTestHelper {
private final RowContentBindStage mBindStage;
private final IconManager mIconManager;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardBypassController mKeyguardBypassController;
private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
private final OnUserInteractionCallback mOnUserInteractionCallback;
private final NotificationDismissibilityProvider mDismissibilityProvider;
@@ -139,6 +142,7 @@ public class NotificationTestHelper {
dependency.injectMockDependency(MediaOutputDialogFactory.class);
mMockLogger = mock(ExpandableNotificationRowLogger.class);
mStatusBarStateController = mock(StatusBarStateController.class);
mKeyguardBypassController = mock(KeyguardBypassController.class);
mGroupMembershipManager = mock(GroupMembershipManager.class);
mGroupExpansionManager = mock(GroupExpansionManager.class);
mHeadsUpManager = mock(HeadsUpManagerPhone.class);
@@ -308,6 +312,21 @@ public class NotificationTestHelper {
return row;
}
/**
* Returns an {@link ExpandableNotificationRow} that shows as a sticky FSI HUN.
*/
public ExpandableNotificationRow createStickyRow()
throws Exception {
Notification n = createNotification(false /* isGroupSummary */,
null /* groupKey */,
makeBubbleMetadata(null /* deleteIntent */, false /* autoExpand */));
n.flags |= FLAG_FSI_REQUESTED_BUT_DENIED;
ExpandableNotificationRow row = generateRow(n, PKG, UID, USER_HANDLE,
mDefaultInflationFlags, IMPORTANCE_HIGH);
return row;
}
/**
* Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
*/
@@ -483,6 +502,10 @@ public class NotificationTestHelper {
return mStatusBarStateController;
}
public KeyguardBypassController getKeyguardBypassController() {
return mKeyguardBypassController;
}
private ExpandableNotificationRow generateRow(
Notification notification,
String pkg,
@@ -541,7 +564,7 @@ public class NotificationTestHelper {
APP_NAME,
entry.getKey(),
mMockLogger,
mock(KeyguardBypassController.class),
mKeyguardBypassController,
mGroupMembershipManager,
mGroupExpansionManager,
mHeadsUpManager,

View File

@@ -218,6 +218,25 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
assertThat(space).isEqualTo(5)
}
@Test
fun spaceNeeded_fsiHunOnLockscreen_usesIntrinsicHeight() {
setGapHeight(0f)
// No divider height since we're testing one element where index = 0
val expandableView = createMockStickyRow(rowHeight)
whenever(expandableView.getMinHeight(any())).thenReturn(5)
whenever(expandableView.intrinsicHeight).thenReturn(10)
val space =
sizeCalculator.spaceNeeded(
expandableView,
visibleIndex = 0,
previousView = null,
stack = stackLayout,
onLockscreen = true)
assertThat(space).isEqualTo(10)
}
@Test
fun spaceNeeded_notOnLockscreen_usesIntrinsicHeight() {
setGapHeight(0f)
@@ -276,6 +295,25 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
return row
}
private fun createMockStickyRow(
height: Float = rowHeight,
isRemoved: Boolean = false,
visibility: Int = VISIBLE
): ExpandableNotificationRow {
val row = mock(ExpandableNotificationRow::class.java)
val entry = mock(NotificationEntry::class.java)
whenever(entry.isStickyAndNotDemoted).thenReturn(true)
val sbn = mock(StatusBarNotification::class.java)
whenever(entry.sbn).thenReturn(sbn)
whenever(row.entry).thenReturn(entry)
whenever(row.isRemoved).thenReturn(isRemoved)
whenever(row.visibility).thenReturn(visibility)
whenever(row.getMinHeight(any())).thenReturn(height.toInt())
whenever(row.intrinsicHeight).thenReturn(height.toInt())
return row
}
private fun setGapHeight(height: Float) {
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any())).thenReturn(height)
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), /* visibleIndex= */ eq(0)))