Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +28 −16 Original line number Diff line number Diff line Loading @@ -870,7 +870,8 @@ public class StackScrollAlgorithm { } for (int i = childCount - 1; i >= 0; i--) { updateChildZValue(i, algorithmState, ambientState, i == topHunIndex); childrenOnTop = updateChildZValue(i, childrenOnTop, algorithmState, ambientState, i == topHunIndex); } } Loading @@ -880,8 +881,12 @@ public class StackScrollAlgorithm { * * @param isTopHun Whether the child is a top HUN. A top HUN means a HUN that shows on the * vertically top of screen. Top HUNs should have drop shadows * @param childrenOnTop It is greater than 0 when there's an existing HUN that is elevated * @return childrenOnTop The decimal part represents the fraction of the elevated HUN's height * that overlaps with QQS Panel. The integer part represents the count of * previous HUNs whose Z positions are greater than 0. */ protected void updateChildZValue(int i, protected float updateChildZValue(int i, float childrenOnTop, StackScrollAlgorithmState algorithmState, AmbientState ambientState, boolean isTopHun) { Loading @@ -898,16 +903,22 @@ public class StackScrollAlgorithm { // Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0 // Calculate the HUN's z-value based on its overlapping fraction with QQS Panel. // When scrolling down shade to make HUN back to in-position in Notification Panel, // the overlapFraction goes to 0, and the pinned HUN's shadows hides gradually. // The over-lapping fraction goes to 0, and shadows hides gradually. if (childrenOnTop != 0.0f) { // To elevate the later HUN over previous HUN childrenOnTop++; } else { float overlap = ambientState.getTopPadding() + ambientState.getStackTranslation() - childViewState.getYTranslation(); if (childViewState.height > 0) { // To avoid 0/0 problems // To prevent over-shadow float overlapFraction = MathUtils.saturate(overlap / childViewState.height); childViewState.setZTranslation(baseZ + overlapFraction * mPinnedZTranslationExtra); // To prevent over-shadow during HUN entry childrenOnTop += Math.min( 1.0f, overlap / childViewState.height ); MathUtils.saturate(childrenOnTop); } childViewState.setZTranslation(baseZ + childrenOnTop * mPinnedZTranslationExtra); } else if (isTopHun) { // In case this is a new view that has never been measured before, we don't want to // elevate if we are currently expanded more than the notification Loading Loading @@ -935,14 +946,15 @@ public class StackScrollAlgorithm { } // Handles HUN shadow when shade is closed. // While shade is closed, and during HUN's entry: headerVisibleAmount stays 0, shadow stays. // While shade is closed, and HUN is showing: headerVisibleAmount stays 0, shadow stays. // While HUN is showing and Shade is closed: headerVisibleAmount stays 0, shadow stays. // During HUN-to-Shade (eg. dragging down HUN to open Shade): headerVisibleAmount goes // gradually from 0 to 1, shadow hides gradually. // Header visibility is a deprecated concept, we are using headerVisibleAmount only because // this value nicely goes from 0 to 1 during the HUN-to-Shade process. childViewState.setZTranslation(childViewState.getZTranslation() + (1.0f - child.getHeaderVisibleAmount()) * mPinnedZTranslationExtra); return childrenOnTop; } public void setIsExpanded(boolean isExpanded) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +12 −10 Original line number Diff line number Diff line Loading @@ -518,7 +518,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = false, headerVisibleAmount = 1f, headerVisibleAmount = 1f ) val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState() algorithmState.visibleChildren.add(childHunView) Loading @@ -526,6 +526,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -545,7 +546,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = false, headerVisibleAmount = 1f, headerVisibleAmount = 1f ) // Use half of the HUN's height as overlap childHunView.viewState.yTranslation = (childHunView.viewState.height + 1 shr 1).toFloat() Loading @@ -555,6 +556,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -578,7 +580,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = true, headerVisibleAmount = 1f, headerVisibleAmount = 1f ) // HUN doesn't overlap with QQS Panel childHunView.viewState.yTranslation = ambientState.topPadding + Loading @@ -589,6 +591,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -608,7 +611,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = false, fullyVisible = false, headerVisibleAmount = 0f, headerVisibleAmount = 0f ) childHunView.viewState.yTranslation = 0f // Shade is closed, thus childHunView's headerVisibleAmount is 0 Loading @@ -619,6 +622,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -638,7 +642,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = false, fullyVisible = false, headerVisibleAmount = 0.5f, headerVisibleAmount = 0.5f ) childHunView.viewState.yTranslation = 0f // Shade is being opened, thus childHunView's headerVisibleAmount is between 0 and 1 Loading @@ -650,6 +654,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -664,7 +669,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { private fun createHunViewMock( isShadeOpen: Boolean, fullyVisible: Boolean, headerVisibleAmount: Float, headerVisibleAmount: Float ) = mock<ExpandableNotificationRow>().apply { val childViewStateMock = createHunChildViewState(isShadeOpen, fullyVisible) Loading @@ -675,10 +680,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } private fun createHunChildViewState( isShadeOpen: Boolean, fullyVisible: Boolean, ) = private fun createHunChildViewState(isShadeOpen: Boolean, fullyVisible: Boolean) = ExpandableViewState().apply { // Mock the HUN's height with ambientState.topPadding + // ambientState.stackTranslation Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +28 −16 Original line number Diff line number Diff line Loading @@ -870,7 +870,8 @@ public class StackScrollAlgorithm { } for (int i = childCount - 1; i >= 0; i--) { updateChildZValue(i, algorithmState, ambientState, i == topHunIndex); childrenOnTop = updateChildZValue(i, childrenOnTop, algorithmState, ambientState, i == topHunIndex); } } Loading @@ -880,8 +881,12 @@ public class StackScrollAlgorithm { * * @param isTopHun Whether the child is a top HUN. A top HUN means a HUN that shows on the * vertically top of screen. Top HUNs should have drop shadows * @param childrenOnTop It is greater than 0 when there's an existing HUN that is elevated * @return childrenOnTop The decimal part represents the fraction of the elevated HUN's height * that overlaps with QQS Panel. The integer part represents the count of * previous HUNs whose Z positions are greater than 0. */ protected void updateChildZValue(int i, protected float updateChildZValue(int i, float childrenOnTop, StackScrollAlgorithmState algorithmState, AmbientState ambientState, boolean isTopHun) { Loading @@ -898,16 +903,22 @@ public class StackScrollAlgorithm { // Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0 // Calculate the HUN's z-value based on its overlapping fraction with QQS Panel. // When scrolling down shade to make HUN back to in-position in Notification Panel, // the overlapFraction goes to 0, and the pinned HUN's shadows hides gradually. // The over-lapping fraction goes to 0, and shadows hides gradually. if (childrenOnTop != 0.0f) { // To elevate the later HUN over previous HUN childrenOnTop++; } else { float overlap = ambientState.getTopPadding() + ambientState.getStackTranslation() - childViewState.getYTranslation(); if (childViewState.height > 0) { // To avoid 0/0 problems // To prevent over-shadow float overlapFraction = MathUtils.saturate(overlap / childViewState.height); childViewState.setZTranslation(baseZ + overlapFraction * mPinnedZTranslationExtra); // To prevent over-shadow during HUN entry childrenOnTop += Math.min( 1.0f, overlap / childViewState.height ); MathUtils.saturate(childrenOnTop); } childViewState.setZTranslation(baseZ + childrenOnTop * mPinnedZTranslationExtra); } else if (isTopHun) { // In case this is a new view that has never been measured before, we don't want to // elevate if we are currently expanded more than the notification Loading Loading @@ -935,14 +946,15 @@ public class StackScrollAlgorithm { } // Handles HUN shadow when shade is closed. // While shade is closed, and during HUN's entry: headerVisibleAmount stays 0, shadow stays. // While shade is closed, and HUN is showing: headerVisibleAmount stays 0, shadow stays. // While HUN is showing and Shade is closed: headerVisibleAmount stays 0, shadow stays. // During HUN-to-Shade (eg. dragging down HUN to open Shade): headerVisibleAmount goes // gradually from 0 to 1, shadow hides gradually. // Header visibility is a deprecated concept, we are using headerVisibleAmount only because // this value nicely goes from 0 to 1 during the HUN-to-Shade process. childViewState.setZTranslation(childViewState.getZTranslation() + (1.0f - child.getHeaderVisibleAmount()) * mPinnedZTranslationExtra); return childrenOnTop; } public void setIsExpanded(boolean isExpanded) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +12 −10 Original line number Diff line number Diff line Loading @@ -518,7 +518,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = false, headerVisibleAmount = 1f, headerVisibleAmount = 1f ) val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState() algorithmState.visibleChildren.add(childHunView) Loading @@ -526,6 +526,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -545,7 +546,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = false, headerVisibleAmount = 1f, headerVisibleAmount = 1f ) // Use half of the HUN's height as overlap childHunView.viewState.yTranslation = (childHunView.viewState.height + 1 shr 1).toFloat() Loading @@ -555,6 +556,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -578,7 +580,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = true, fullyVisible = true, headerVisibleAmount = 1f, headerVisibleAmount = 1f ) // HUN doesn't overlap with QQS Panel childHunView.viewState.yTranslation = ambientState.topPadding + Loading @@ -589,6 +591,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -608,7 +611,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = false, fullyVisible = false, headerVisibleAmount = 0f, headerVisibleAmount = 0f ) childHunView.viewState.yTranslation = 0f // Shade is closed, thus childHunView's headerVisibleAmount is 0 Loading @@ -619,6 +622,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -638,7 +642,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { val childHunView = createHunViewMock( isShadeOpen = false, fullyVisible = false, headerVisibleAmount = 0.5f, headerVisibleAmount = 0.5f ) childHunView.viewState.yTranslation = 0f // Shade is being opened, thus childHunView's headerVisibleAmount is between 0 and 1 Loading @@ -650,6 +654,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { // When: updateChildZValue() is called for the top HUN stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, /* StackScrollAlgorithmState= */ algorithmState, /* ambientState= */ ambientState, /* shouldElevateHun= */ true Loading @@ -664,7 +669,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { private fun createHunViewMock( isShadeOpen: Boolean, fullyVisible: Boolean, headerVisibleAmount: Float, headerVisibleAmount: Float ) = mock<ExpandableNotificationRow>().apply { val childViewStateMock = createHunChildViewState(isShadeOpen, fullyVisible) Loading @@ -675,10 +680,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } private fun createHunChildViewState( isShadeOpen: Boolean, fullyVisible: Boolean, ) = private fun createHunChildViewState(isShadeOpen: Boolean, fullyVisible: Boolean) = ExpandableViewState().apply { // Mock the HUN's height with ambientState.topPadding + // ambientState.stackTranslation Loading