Merge "[Flexiglass] Replace StackY with StackTop" into main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 456c321..2cbb6ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -64,6 +64,7 @@
* Used to read bouncer states.
*/
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private float mStackTop;
private float mStackCutoff;
private int mScrollY;
private float mOverScrollTopAmount;
@@ -186,6 +187,7 @@
* @param stackY Distance of top of notifications panel from top of screen.
*/
public void setStackY(float stackY) {
+ SceneContainerFlag.assertInLegacyMode();
mStackY = stackY;
}
@@ -193,6 +195,7 @@
* @return Distance of top of notifications panel from top of screen.
*/
public float getStackY() {
+ SceneContainerFlag.assertInLegacyMode();
return mStackY;
}
@@ -348,6 +351,18 @@
return mZDistanceBetweenElements;
}
+ /** Y coordinate in view pixels of the top of the notification stack */
+ public float getStackTop() {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return 0f;
+ return mStackTop;
+ }
+
+ /** @see #getStackTop() */
+ public void setStackTop(float mStackTop) {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+ this.mStackTop = mStackTop;
+ }
+
/**
* Y coordinate in view pixels above which the bottom of the notification stack / shelf / footer
* must be.
@@ -769,6 +784,8 @@
@Override
public void dump(PrintWriter pw, String[] args) {
+ pw.println("mStackTop=" + mStackTop);
+ pw.println("mStackCutoff" + mStackCutoff);
pw.println("mTopPadding=" + mTopPadding);
pw.println("mStackTopMargin=" + mStackTopMargin);
pw.println("mStackTranslation=" + mStackTranslation);
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 38bcc0b..1eee466 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
@@ -834,7 +834,7 @@
drawDebugInfo(canvas, y, Color.RED, /* label= */ "y = " + y);
if (SceneContainerFlag.isEnabled()) {
- y = (int) mScrollViewFields.getStackTop();
+ y = (int) mAmbientState.getStackTop();
drawDebugInfo(canvas, y, Color.RED, /* label= */ "getStackTop() = " + y);
y = (int) mAmbientState.getStackCutoff();
@@ -1216,7 +1216,7 @@
@Override
public void setStackTop(float stackTop) {
- mScrollViewFields.setStackTop(stackTop);
+ mAmbientState.setStackTop(stackTop);
// TODO(b/332574413): replace the following with using stackTop
updateTopPadding(stackTop, isAddOrRemoveAnimationPending());
}
@@ -1426,11 +1426,7 @@
if (mAmbientState.isBouncerInTransit() && mQsExpansionFraction > 0f) {
fraction = BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(fraction);
}
- // TODO(b/322228881): Clean up scene container vs legacy behavior in NSSL
- if (SceneContainerFlag.isEnabled()) {
- // stackY should be driven by scene container, not NSSL
- mAmbientState.setStackY(getTopPadding());
- } else {
+ if (!SceneContainerFlag.isEnabled()) {
final float stackY = MathUtils.lerp(0, endTopPosition, fraction);
mAmbientState.setStackY(stackY);
}
@@ -3726,7 +3722,7 @@
protected boolean isInsideQsHeader(MotionEvent ev) {
if (SceneContainerFlag.isEnabled()) {
- return ev.getY() < mScrollViewFields.getStackTop();
+ return ev.getY() < mAmbientState.getStackTop();
}
mQsHeader.getBoundsOnScreen(mQsHeaderBound);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
index 2e86ad9..97ec391 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
@@ -32,8 +32,6 @@
class ScrollViewFields {
/** Used to produce the clipping path */
var scrimClippingShape: ShadeScrimShape? = null
- /** Y coordinate in view pixels of the top of the notification stack */
- var stackTop: Float = 0f
/** Y coordinate in view pixels of the top of the HUN */
var headsUpTop: Float = 0f
/** Whether the notifications are scrolled all the way to the top (i.e. when freshly opened) */
@@ -76,7 +74,6 @@
fun dump(pw: IndentingPrintWriter) {
pw.printSection("StackViewStates") {
pw.println("scrimClippingShape", scrimClippingShape)
- pw.println("stackTop", stackTop)
pw.println("headsUpTop", headsUpTop)
pw.println("isScrolledToTop", isScrolledToTop)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index f9efc07..ca74c0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -29,6 +29,7 @@
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationShelf;
@@ -332,8 +333,10 @@
private void updateClipping(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
- float drawStart = ambientState.isOnKeyguard() ? 0
+ float stackTop = SceneContainerFlag.isEnabled() ? ambientState.getStackTop()
: ambientState.getStackY() - ambientState.getScrollY();
+ float drawStart = ambientState.isOnKeyguard() ? 0
+ : stackTop;
float clipStart = 0;
int childCount = algorithmState.visibleChildren.size();
boolean firstHeadsUp = true;
@@ -641,7 +644,10 @@
// Incoming views have yTranslation=0 by default.
viewState.setYTranslation(algorithmState.mCurrentYPosition);
- float viewEnd = viewState.getYTranslation() + viewState.height + ambientState.getStackY();
+ float stackTop = SceneContainerFlag.isEnabled()
+ ? ambientState.getStackTop()
+ : ambientState.getStackY();
+ float viewEnd = stackTop + viewState.getYTranslation() + viewState.height;
maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(),
view.mustStayOnScreen(),
/* topVisible= */ viewState.getYTranslation() >= mNotificationScrimPadding,
@@ -681,7 +687,9 @@
}
} else {
if (view instanceof EmptyShadeView) {
- float fullHeight = ambientState.getLayoutMaxHeight() + mMarginBottom
+ float fullHeight = SceneContainerFlag.isEnabled()
+ ? ambientState.getStackCutoff() - ambientState.getStackTop()
+ : ambientState.getLayoutMaxHeight() + mMarginBottom
- ambientState.getStackY();
viewState.setYTranslation((fullHeight - getMaxAllowedChildHeight(view)) / 2f);
} else if (view != ambientState.getTrackedHeadsUpRow()) {
@@ -726,7 +734,7 @@
+ mPaddingBetweenElements;
setLocation(view.getViewState(), algorithmState.mCurrentYPosition, i);
- viewState.setYTranslation(viewState.getYTranslation() + ambientState.getStackY());
+ viewState.setYTranslation(viewState.getYTranslation() + stackTop);
}
@VisibleForTesting
@@ -1002,8 +1010,11 @@
// Animate pinned HUN bottom corners to and from original roundness.
final float originalCornerRadius =
row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius);
+ final float stackTop = SceneContainerFlag.isEnabled()
+ ? ambientState.getStackTop()
+ : ambientState.getStackY();
final float bottomValue = computeCornerRoundnessForPinnedHun(mHostView.getHeight(),
- ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius);
+ stackTop, getMaxAllowedChildHeight(row), originalCornerRadius);
row.requestBottomRoundness(bottomValue, STACK_SCROLL_ALGO);
row.addOnDetachResetRoundness(STACK_SCROLL_ALGO);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 12f3ef3..967f95e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -214,6 +214,7 @@
}
@Test
+ @DisableSceneContainer // TODO(b/332574413) cover stack bounds integration with tests
public void testUpdateStackHeight_qsExpansionGreaterThanZero() {
final float expansionFraction = 0.2f;
final float overExpansion = 50f;
@@ -891,6 +892,7 @@
}
@Test
+ @DisableSceneContainer // NSSL has no more scroll logic when SceneContainer is on
public void testNormalShade_hasNoTopOverscroll() {
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index d28e0c1..8401a19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -11,6 +11,8 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.res.R
@@ -66,7 +68,7 @@
EmptyShadeView(context, /* attrs= */ null).apply {
layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
}
- private val footerView = FooterView(context, /*attrs=*/ null)
+ private val footerView = FooterView(context, /* attrs= */ null)
@OptIn(ExperimentalCoroutinesApi::class)
private val ambientState =
AmbientState(
@@ -126,6 +128,7 @@
}
@Test
+ @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests
fun resetViewStates_defaultHunWhenShadeIsOpening_yTranslationIsInset() {
whenever(notificationRow.isPinned).thenReturn(true)
whenever(notificationRow.isHeadsUp).thenReturn(true)
@@ -168,6 +171,7 @@
}
@Test
+ @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests
@EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
fun resetViewStates_defaultHun_showingQS_newHeadsUpAnim_hunTranslatedToMax() {
// Given: the shade is open and scrolled to the bottom to show the QuickSettings
@@ -184,6 +188,7 @@
}
@Test
+ @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests
@EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
fun resetViewStates_hunAnimatingAway_showingQS_newHeadsUpAnim_hunTranslatedToBottomOfScreen() {
// Given: the shade is open and scrolled to the bottom to show the QuickSettings
@@ -272,6 +277,27 @@
}
@Test
+ @EnableSceneContainer
+ fun resetViewStates_emptyShadeView_isCenteredVertically_withSceneContainer() {
+ stackScrollAlgorithm.initView(context)
+ hostView.removeAllViews()
+ hostView.addView(emptyShadeView)
+ ambientState.layoutMaxHeight = maxPanelHeight.toInt()
+
+ val stackTop = 200f
+ val stackBottom = 2000f
+ val stackHeight = stackBottom - stackTop
+ ambientState.stackTop = stackTop
+ ambientState.stackCutoff = stackBottom
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ val centeredY = stackTop + stackHeight / 2f - emptyShadeView.height / 2f
+ assertThat(emptyShadeView.viewState.yTranslation).isEqualTo(centeredY)
+ }
+
+ @Test
+ @DisableSceneContainer
fun resetViewStates_emptyShadeView_isCenteredVertically() {
stackScrollAlgorithm.initView(context)
hostView.removeAllViews()
@@ -1157,6 +1183,7 @@
assertFalse(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState))
}
+
// endregion
private fun createHunViewMock(