Merge "Add overscroll effect to top of split shade" into tm-qpr-dev

This commit is contained in:
Johannes Gallmann
2022-12-20 13:33:53 +00:00
committed by Android (Google) Code Review
2 changed files with 53 additions and 8 deletions

View File

@@ -146,7 +146,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private static final int DELAY_BEFORE_SHADE_CLOSE = 200;
private boolean mShadeNeedsToClose = false;
private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
@VisibleForTesting
static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
private static final float RUBBER_BAND_FACTOR_ON_PANEL_EXPAND = 0.21f;
/**
@@ -1326,8 +1327,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
* @param listenerNeedsAnimation does the listener need to animate?
*/
private void updateStackPosition(boolean listenerNeedsAnimation) {
float topOverscrollAmount = mShouldUseSplitNotificationShade
? getCurrentOverScrollAmount(true /* top */) : 0f;
final float endTopPosition = mTopPadding + mExtraTopInsetForFullShadeTransition
+ mAmbientState.getOverExpansion()
+ topOverscrollAmount
- getCurrentOverScrollAmount(false /* top */);
float fraction = mAmbientState.getExpansionFraction();
// If we are on quick settings, we need to quickly hide it to show the bouncer to avoid an
@@ -2613,8 +2617,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
float bottomAmount = getCurrentOverScrollAmount(false);
if (velocityY < 0 && topAmount > 0) {
setOwnScrollY(mOwnScrollY - (int) topAmount);
mDontReportNextOverScroll = true;
setOverScrollAmount(0, true, false);
if (!mShouldUseSplitNotificationShade) {
mDontReportNextOverScroll = true;
setOverScrollAmount(0, true, false);
}
mMaxOverScroll = Math.abs(velocityY) / 1000f * getRubberBandFactor(true /* onTop */)
* mOverflingDistance + topAmount;
} else if (velocityY > 0 && bottomAmount > 0) {
@@ -2648,6 +2654,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
float topOverScroll = getCurrentOverScrollAmount(true);
return mScrolledToTopOnFirstDown
&& !mExpandedInThisMotion
&& !mShouldUseSplitNotificationShade
&& (initialVelocity > mMinimumVelocity
|| (topOverScroll > mMinTopOverScrollToEscape && initialVelocity > 0));
}
@@ -2713,7 +2720,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
return RUBBER_BAND_FACTOR_AFTER_EXPAND;
} else if (mIsExpansionChanging || mPanelTracking) {
return RUBBER_BAND_FACTOR_ON_PANEL_EXPAND;
} else if (mScrolledToTopOnFirstDown) {
} else if (mScrolledToTopOnFirstDown && !mShouldUseSplitNotificationShade) {
return 1.0f;
}
return RUBBER_BAND_FACTOR_NORMAL;
@@ -5705,7 +5712,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
}
private void updateSplitNotificationShade() {
@VisibleForTesting
void updateSplitNotificationShade() {
boolean split = LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
if (split != mShouldUseSplitNotificationShade) {
mShouldUseSplitNotificationShade = split;

View File

@@ -20,6 +20,7 @@ import static android.view.View.GONE;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.RUBBER_BAND_FACTOR_NORMAL;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -47,6 +48,7 @@ import static org.mockito.Mockito.when;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
@@ -99,6 +101,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
private NotificationStackScrollLayout mStackScroller; // Normally test this
private NotificationStackScrollLayout mStackScrollerInternal; // See explanation below
private AmbientState mAmbientState;
private TestableResources mTestableResources;
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Mock private CentralSurfaces mCentralSurfaces;
@@ -123,6 +126,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@UiThreadTest
public void setUp() throws Exception {
allowTestableLooperAsMainThread();
mTestableResources = mContext.getOrCreateTestableResources();
// Interact with real instance of AmbientState.
mAmbientState = spy(new AmbientState(
@@ -394,7 +398,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
@UiThreadTest
public void testSetExpandedHeight_withSplitShade_doesntInterpolateStackHeight() {
mContext.getOrCreateTestableResources()
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
final int[] expectedStackHeight = {0};
@@ -405,12 +409,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
.isEqualTo(expectedStackHeight[0]);
});
mContext.getOrCreateTestableResources()
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
expectedStackHeight[0] = 0;
mStackScroller.setExpandedHeight(100f);
mContext.getOrCreateTestableResources()
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
expectedStackHeight[0] = 100;
mStackScroller.setExpandedHeight(100f);
@@ -781,6 +785,39 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
assertEquals(mAmbientState.getScrollY(), 0);
}
@Test
public void testSplitShade_hasTopOverscroll() {
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
mStackScroller.updateSplitNotificationShade();
mAmbientState.setExpansionFraction(1f);
int topOverscrollPixels = 100;
mStackScroller.setOverScrolledPixels(topOverscrollPixels, true, false);
float expectedTopOverscrollAmount = topOverscrollPixels * RUBBER_BAND_FACTOR_NORMAL;
assertEquals(expectedTopOverscrollAmount, mStackScroller.getCurrentOverScrollAmount(true));
assertEquals(expectedTopOverscrollAmount, mAmbientState.getStackY());
}
@Test
public void testNormalShade_hasNoTopOverscroll() {
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
mStackScroller.updateSplitNotificationShade();
mAmbientState.setExpansionFraction(1f);
int topOverscrollPixels = 100;
mStackScroller.setOverScrolledPixels(topOverscrollPixels, true, false);
float expectedTopOverscrollAmount = topOverscrollPixels * RUBBER_BAND_FACTOR_NORMAL;
assertEquals(expectedTopOverscrollAmount, mStackScroller.getCurrentOverScrollAmount(true));
// When not in split shade mode, then the overscroll effect is handled in
// NotificationPanelViewController and not in NotificationStackScrollLayout. Therefore
// mAmbientState must have stackY set to 0
assertEquals(0f, mAmbientState.getStackY());
}
private void setBarStateForTest(int state) {
// Can't inject this through the listener or we end up on the actual implementation
// rather than the mock because the spy just coppied the anonymous inner /shruggie.