Fix white line before shelf on lockscreen

Use float instead of int to keep precision
Add tests for view visibility w.r.t. shelf

Fixes: 231397826
Test: StackScrollAlgorithmTest
Test: see no white line during ls <=> aod transitions
Change-Id: I90ea049d557cb26ab4880a6d3f333f3659cc3f47
This commit is contained in:
Lyn Han
2022-05-19 14:11:24 -07:00
parent 7ab7a81845
commit 91044e2bba
3 changed files with 83 additions and 27 deletions

View File

@@ -191,7 +191,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private final boolean mDebugRemoveAnimation;
private int mContentHeight;
private int mIntrinsicContentHeight;
private float mIntrinsicContentHeight;
private int mCollapsedSize;
private int mPaddingBetweenElements;
private int mMaxTopPadding;
@@ -802,7 +802,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
drawDebugInfo(canvas, y, Color.MAGENTA,
/* label= */ "mAmbientState.getStackY() + mContentHeight = " + y);
y = (int) mAmbientState.getStackY() + mIntrinsicContentHeight;
y = (int) (mAmbientState.getStackY() + mIntrinsicContentHeight);
drawDebugInfo(canvas, y, Color.YELLOW,
/* label= */ "mAmbientState.getStackY() + mIntrinsicContentHeight = " + y);
@@ -1473,7 +1473,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
*/
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
public int getIntrinsicContentHeight() {
return mIntrinsicContentHeight;
return (int) mIntrinsicContentHeight;
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -2280,7 +2280,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private void updateContentHeight() {
final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
final int height =
final float height =
(int) scrimTopPadding + (int) mNotificationStackSizeCalculator.computeHeight(
/* notificationStackScrollLayout= */ this, mMaxDisplayedNotifications,
shelfIntrinsicHeight);
@@ -2288,7 +2288,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
// The topPadding can be bigger than the regular padding when qs is expanded, in that
// state the maxPanelHeight and the contentHeight should be bigger
mContentHeight = height + Math.max(mIntrinsicPadding, mTopPadding) + mBottomPadding;
mContentHeight = (int) (height + Math.max(mIntrinsicPadding, mTopPadding) + mBottomPadding);
updateScrollability();
clampScrollPosition();
updateStackPosition();

View File

@@ -53,9 +53,9 @@ public class StackScrollAlgorithm {
private static final Boolean DEBUG = false;
private final ViewGroup mHostView;
private int mPaddingBetweenElements;
private int mGapHeight;
private int mGapHeightOnLockscreen;
private float mPaddingBetweenElements;
private float mGapHeight;
private float mGapHeightOnLockscreen;
private int mCollapsedSize;
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
@@ -127,13 +127,13 @@ public class StackScrollAlgorithm {
return getExpansionFractionWithoutShelf(mTempAlgorithmState, ambientState);
}
private void log(String s) {
public static void log(String s) {
if (DEBUG) {
android.util.Log.i(TAG, s);
}
}
public void logView(View view, String s) {
public static void logView(View view, String s) {
String viewString = "";
if (view instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = ((ExpandableNotificationRow) view);
@@ -535,30 +535,23 @@ public class StackScrollAlgorithm {
// more notifications than we should during this special transitional states.
boolean bypassPulseNotExpanding = ambientState.isBypassEnabled()
&& ambientState.isOnKeyguard() && !ambientState.isPulseExpanding();
final int stackBottom =
!ambientState.isShadeExpanded() || ambientState.isDozing()
|| bypassPulseNotExpanding
final float stackBottom = !ambientState.isShadeExpanded()
|| ambientState.getDozeAmount() == 1f
|| bypassPulseNotExpanding
? ambientState.getInnerHeight()
: (int) ambientState.getStackHeight();
final int shelfStart = stackBottom
: ambientState.getStackHeight();
final float shelfStart = stackBottom
- ambientState.getShelf().getIntrinsicHeight()
- mPaddingBetweenElements;
viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
if (viewState.yTranslation >= shelfStart) {
viewState.hidden = !view.isExpandAnimationRunning()
&& !view.hasExpandingChild();
viewState.inShelf = true;
// Notifications in the shelf cannot be visible HUNs.
viewState.headsUpIsVisible = false;
}
updateViewWithShelf(view, viewState, shelfStart);
}
}
// Clip height of view right before shelf.
viewState.height = (int) (getMaxAllowedChildHeight(view) * expansionFraction);
}
algorithmState.mCurrentYPosition += viewState.height
+ expansionFraction * mPaddingBetweenElements;
algorithmState.mCurrentYPosition +=
expansionFraction * (getMaxAllowedChildHeight(view) + mPaddingBetweenElements);
algorithmState.mCurrentExpandedYPosition += view.getIntrinsicHeight()
+ mPaddingBetweenElements;
@@ -566,6 +559,18 @@ public class StackScrollAlgorithm {
viewState.yTranslation += ambientState.getStackY();
}
@VisibleForTesting
void updateViewWithShelf(ExpandableView view, ExpandableViewState viewState, float shelfStart) {
viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
if (viewState.yTranslation >= shelfStart) {
viewState.hidden = !view.isExpandAnimationRunning()
&& !view.hasExpandingChild();
viewState.inShelf = true;
// Notifications in the shelf cannot be visible HUNs.
viewState.headsUpIsVisible = false;
}
}
/**
* Get the gap height needed for before a view
*
@@ -849,13 +854,13 @@ public class StackScrollAlgorithm {
* Y position of the current view during updating children
* with expansion factor applied.
*/
private int mCurrentYPosition;
private float mCurrentYPosition;
/**
* Y position of the current view during updating children
* without applying the expansion factor.
*/
private int mCurrentExpandedYPosition;
private float mCurrentExpandedYPosition;
}
/**

View File

@@ -7,10 +7,13 @@ import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.EmptyShadeView
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.mock
@@ -110,4 +113,52 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
/* fractionToShade= */ 0f, /* onKeyguard= */ false)
assertThat(gap).isEqualTo(bigGap)
}
@Test
fun updateViewWithShelf_viewAboveShelf_viewShown() {
val viewStart = 0f
val shelfStart = 1f
val expandableView = mock(ExpandableView::class.java)
whenever(expandableView.isExpandAnimationRunning).thenReturn(false)
whenever(expandableView.hasExpandingChild()).thenReturn(false)
val expandableViewState = ExpandableViewState()
expandableViewState.yTranslation = viewStart
stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart);
assertFalse(expandableViewState.hidden)
}
@Test
fun updateViewWithShelf_viewBelowShelf_viewHidden() {
val shelfStart = 0f
val viewStart = 1f
val expandableView = mock(ExpandableView::class.java)
whenever(expandableView.isExpandAnimationRunning).thenReturn(false)
whenever(expandableView.hasExpandingChild()).thenReturn(false)
val expandableViewState = ExpandableViewState()
expandableViewState.yTranslation = viewStart
stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart);
assertTrue(expandableViewState.hidden)
}
@Test
fun updateViewWithShelf_viewBelowShelfButIsExpanding_viewShown() {
val shelfStart = 0f
val viewStart = 1f
val expandableView = mock(ExpandableView::class.java)
whenever(expandableView.isExpandAnimationRunning).thenReturn(true)
whenever(expandableView.hasExpandingChild()).thenReturn(true)
val expandableViewState = ExpandableViewState()
expandableViewState.yTranslation = viewStart
stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart);
assertFalse(expandableViewState.hidden)
}
}