summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author András Kurucz <kurucz@google.com> 2024-11-13 13:30:29 +0000
committer András Kurucz <kurucz@google.com> 2024-11-20 12:52:45 +0000
commit152e4e9536ca51528c52d9052c87e2f6592cd445 (patch)
treec93b3a4a79d41258507ded797fbbe0f202b6f203
parent4f2d2366e9a37d07e52c8ee0c9c70413166d900d (diff)
[flexiglass] Patch for the unfurl animation
When we pull down the shade from the Lockscreen, and we navigate to the Locked shade, there are a few things happening: - ExpandableNotificationRow#isOnKeyguard() changes - ExpandableNotificationRow#getIntrinsicHeight() changes - NSSL#getIntrinsicStackHeight() changes - NSSL#mMaxDisplayedNotifications changes In order to orchestrate the same unfurl animations every time we open the locked shade, we need to make these changes in the same frame, and as well request a "goToFullShade" animation from the NSSL. To guarantee that these things are happeing together under flexiglass, let's update them from the same flow. Fixes: 359875442 Test: observe the LS -> Locked Shade animation Flag: com.android.systemui.scene_container Change-Id: I083472c936d9057544c71ab58a7162b15465f9ec
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt45
8 files changed, 118 insertions, 33 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index a940ed4d70f9..f48fd3c998b1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -838,27 +838,26 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
testScope.runTest {
var notificationCount = 10
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
- val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
showLockscreen()
shadeTestUtil.setSplitShade(false)
configurationRepository.onAnyConfigurationChange()
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
// Also updates when directly requested (as it would from NotificationStackScrollLayout)
notificationCount = 25
sharedNotificationContainerInteractor.notificationStackChanged()
advanceTimeBy(50L)
- assertThat(maxNotifications).isEqualTo(25)
+ assertThat(config?.maxNotifications).isEqualTo(25)
// Also ensure another collection starts with the same value. As an example, folding
// then unfolding will restart the coroutine and it must get the last value immediately.
- val newMaxNotifications by
- collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val newConfig by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
- assertThat(newMaxNotifications).isEqualTo(25)
+ assertThat(newConfig?.maxNotifications).isEqualTo(25)
}
@Test
@@ -866,18 +865,18 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
testScope.runTest {
var notificationCount = 10
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
- val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
showLockscreen()
shadeTestUtil.setSplitShade(false)
configurationRepository.onAnyConfigurationChange()
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
// Shade expanding... still 10
shadeTestUtil.setLockscreenShadeExpansion(0.5f)
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
notificationCount = 25
@@ -885,20 +884,20 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
shadeTestUtil.setLockscreenShadeTracking(true)
// Should still be 10, since the user is interacting
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
shadeTestUtil.setLockscreenShadeTracking(false)
shadeTestUtil.setLockscreenShadeExpansion(0f)
// Stopped tracking, show 25
- assertThat(maxNotifications).isEqualTo(25)
+ assertThat(config?.maxNotifications).isEqualTo(25)
}
@Test
fun maxNotificationsOnShade() =
testScope.runTest {
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> 10 }
- val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
// Show lockscreen with shade expanded
@@ -908,7 +907,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
configurationRepository.onAnyConfigurationChange()
// -1 means No Limit
- assertThat(maxNotifications).isEqualTo(-1)
+ assertThat(config?.maxNotifications).isEqualTo(-1)
}
@Test
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 08d177f933c1..ab27fe4e915a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1532,6 +1532,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mPrivateLayout.getSingleLineView();
}
+ /**
+ * Whether this row is displayed over the unoccluded lockscreen. Returns false on the
+ * locked shade.
+ */
public boolean isOnKeyguard() {
return mOnKeyguard;
}
@@ -2811,7 +2815,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
}
- void setOnKeyguard(boolean onKeyguard) {
+ /** @see #isOnKeyguard() */
+ public void setOnKeyguard(boolean onKeyguard) {
if (onKeyguard != mOnKeyguard) {
boolean wasAboveShelf = isAboveShelf();
final boolean wasExpanded = isExpanded();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index baad616cbf02..ffe1b6f88302 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -41,6 +41,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ColorUpdateLogger;
import com.android.systemui.statusbar.notification.FeedbackIcon;
@@ -378,15 +379,19 @@ public class ExpandableNotificationRowController implements NotifViewController
mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
mPluginManager.addPluginListener(mView,
NotificationMenuRowPlugin.class, false /* Allow multiple */);
- mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
- mStatusBarStateController.addCallback(mStatusBarStateListener);
+ if (!SceneContainerFlag.isEnabled()) {
+ mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
+ mStatusBarStateController.addCallback(mStatusBarStateListener);
+ }
mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
mPluginManager.removePluginListener(mView);
- mStatusBarStateController.removeCallback(mStatusBarStateListener);
+ if (!SceneContainerFlag.isEnabled()) {
+ mStatusBarStateController.removeCallback(mStatusBarStateListener);
+ }
mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 5c9a0b939dc7..f85545ef95f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -100,6 +100,9 @@ public interface NotificationListContainer extends
*/
void addContainerViewAt(View v, int index);
+ /** Sets whether the notificatios are displayed on the unoccluded lockscreen. */
+ void setOnLockscreen(boolean isOnKeyguard);
+
/**
* Sets the maximum number of notifications to display.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 57af8ea19722..bddf6dffe7c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -575,6 +575,7 @@ public class NotificationStackScrollLayout
@Nullable private SplitShadeStateController mSplitShadeStateController = null;
private boolean mIsSmallLandscapeLockscreenEnabled = false;
private boolean mSuppressHeightUpdates;
+ private boolean mIsOnLockscreen;
/** Pass splitShadeStateController to view and update split shade */
public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) {
@@ -3228,9 +3229,12 @@ public class NotificationStackScrollLayout
private void onViewAddedInternal(ExpandableView child) {
updateHideSensitiveForChild(child);
child.setOnHeightChangedListener(mOnChildHeightChangedListener);
- if (child instanceof ExpandableNotificationRow) {
+ if (child instanceof ExpandableNotificationRow row) {
NotificationEntry entry = ((ExpandableNotificationRow) child).getEntry();
entry.addOnSensitivityChangedListener(mOnChildSensitivityChangedListener);
+ if (SceneContainerFlag.isEnabled()) {
+ row.setOnKeyguard(mIsOnLockscreen);
+ }
}
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
@@ -4752,8 +4756,11 @@ public class NotificationStackScrollLayout
}
}
- void goToFullShade(long delay) {
- SceneContainerFlag.assertInLegacyMode();
+ /**
+ * Requests an animation for the next stack height update, to animate from the constrained stack
+ * displayed on the lock screen, to the scrollable stack displayed in the expanded shade.
+ */
+ public void animateGoToFullShade(long delay) {
mGoToFullShadeNeedsAnimation = true;
mGoToFullShadeDelay = delay;
mNeedsAnimation = true;
@@ -5356,12 +5363,38 @@ public class NotificationStackScrollLayout
shelf.bind(mAmbientState, this, mController.getNotificationRoundnessManager());
}
+ /**
+ * Whether the notifications are displayed over the unoccluded lockscreen. Returns false on the
+ * locked shade.
+ */
+ public boolean isOnLockscreen() {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return false;
+ return mIsOnLockscreen;
+ }
+
+ /** @see #isOnLockscreen() */
+ public void setOnLockscreen(boolean isOnLockscreen) {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+ if (mIsOnLockscreen != isOnLockscreen) {
+ mIsOnLockscreen = isOnLockscreen;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof ExpandableNotificationRow childRow) {
+ childRow.setOnKeyguard(isOnLockscreen);
+ }
+ }
+ }
+ }
+
public void setMaxDisplayedNotifications(int maxDisplayedNotifications) {
if (mMaxDisplayedNotifications != maxDisplayedNotifications) {
mMaxDisplayedNotifications = maxDisplayedNotifications;
if (SceneContainerFlag.isEnabled()) {
updateIntrinsicStackHeight();
updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
+ if (maxDisplayedNotifications == -1) {
+ animateGoToFullShade(0);
+ }
} else {
updateContentHeight();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index dc1a191ce233..3d7501deafc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -1222,7 +1222,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
public void goToFullShade(long delay) {
SceneContainerFlag.assertInLegacyMode();
- mView.goToFullShade(delay);
+ mView.animateGoToFullShade(delay);
}
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
@@ -1603,6 +1603,12 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
}
+ /** Sets whether the NSSL is displayed over the unoccluded Lockscreen. */
+ public void setOnLockscreen(boolean isOnLockscreen) {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+ mNotificationListContainer.setOnLockscreen(isOnLockscreen);
+ }
+
/**
* Set the maximum number of notifications that can currently be displayed
*/
@@ -2029,6 +2035,11 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
@Override
+ public void setOnLockscreen(boolean isOnLockscreen) {
+ mView.setOnLockscreen(isOnLockscreen);
+ }
+
+ @Override
public void setMaxDisplayedNotifications(int maxNotifications) {
mView.setMaxDisplayedNotifications(maxNotifications);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 4a55dfaaf7ea..ea714608ea66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -118,8 +118,12 @@ constructor(
}
launch {
- viewModel.getMaxNotifications(calculateMaxNotifications).collect {
- controller.setMaxDisplayedNotifications(it)
+ viewModel.getLockscreenDisplayConfig(calculateMaxNotifications).collect {
+ (isOnLockscreen, maxNotifications) ->
+ if (SceneContainerFlag.isEnabled) {
+ controller.setOnLockscreen(isOnLockscreen)
+ }
+ controller.setMaxDisplayedNotifications(maxNotifications)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index fb60f266e188..a55a165d9b66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -718,9 +718,11 @@ constructor(
* When expanding or when the user is interacting with the shade, keep the count stable; do not
* emit a value.
*/
- fun getMaxNotifications(calculateSpace: (Float, Boolean) -> Int): Flow<Int> {
+ fun getLockscreenDisplayConfig(
+ calculateSpace: (Float, Boolean) -> Int
+ ): Flow<LockscreenDisplayConfig> {
val showLimitedNotifications = isOnLockscreenWithoutShade
- val showUnlimitedNotifications =
+ val showUnlimitedNotificationsAndIsOnLockScreen =
combine(
isOnLockscreen,
keyguardInteractor.statusBarState,
@@ -730,28 +732,42 @@ constructor(
)
.onStart { emit(false) },
) { isOnLockscreen, statusBarState, showAllNotifications ->
- statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications
+ (statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications) to
+ isOnLockscreen
}
+ @Suppress("UNCHECKED_CAST")
return combineTransform(
showLimitedNotifications,
- showUnlimitedNotifications,
+ showUnlimitedNotificationsAndIsOnLockScreen,
shadeInteractor.isUserInteracting,
availableHeight,
interactor.notificationStackChanged,
interactor.useExtraShelfSpace,
) { flows ->
val showLimitedNotifications = flows[0] as Boolean
- val showUnlimitedNotifications = flows[1] as Boolean
+ val (showUnlimitedNotifications, isOnLockscreen) =
+ flows[1] as Pair<Boolean, Boolean>
val isUserInteracting = flows[2] as Boolean
val availableHeight = flows[3] as Float
val useExtraShelfSpace = flows[5] as Boolean
if (!isUserInteracting) {
if (showLimitedNotifications) {
- emit(calculateSpace(availableHeight, useExtraShelfSpace))
+ emit(
+ LockscreenDisplayConfig(
+ isOnLockscreen = isOnLockscreen,
+ maxNotifications =
+ calculateSpace(availableHeight, useExtraShelfSpace),
+ )
+ )
} else if (showUnlimitedNotifications) {
- emit(-1)
+ emit(
+ LockscreenDisplayConfig(
+ isOnLockscreen = isOnLockscreen,
+ maxNotifications = -1,
+ )
+ )
}
}
}
@@ -775,9 +791,9 @@ constructor(
SceneContainerFlag.assertInLegacyMode()
return combine(
- getMaxNotifications(calculateMaxNotifications).map {
- val height = calculateHeight(it)
- if (it == 0) {
+ getLockscreenDisplayConfig(calculateMaxNotifications).map { (_, maxNotifications) ->
+ val height = calculateHeight(maxNotifications)
+ if (maxNotifications == 0) {
height - shelfHeight
} else {
height
@@ -815,4 +831,13 @@ constructor(
*/
data class FloatAtEnd(val width: Int) : HorizontalPosition
}
+
+ /**
+ * Data class representing a configuration for displaying Notifications on the Lockscreen.
+ *
+ * @param isOnLockscreen is the user on the lockscreen
+ * @param maxNotifications Limit for the max number of top-level Notifications to be displayed.
+ * A value of -1 indicates no limit.
+ */
+ data class LockscreenDisplayConfig(val isOnLockscreen: Boolean, val maxNotifications: Int)
}