Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +13 −5 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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 Loading Loading @@ -2613,8 +2617,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable float bottomAmount = getCurrentOverScrollAmount(false); if (velocityY < 0 && topAmount > 0) { setOwnScrollY(mOwnScrollY - (int) topAmount); if (!mShouldUseSplitNotificationShade) { mDontReportNextOverScroll = true; setOverScrollAmount(0, true, false); } mMaxOverScroll = Math.abs(velocityY) / 1000f * getRubberBandFactor(true /* onTop */) * mOverflingDistance + topAmount; } else if (velocityY > 0 && bottomAmount > 0) { Loading Loading @@ -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)); } Loading Loading @@ -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; Loading Loading @@ -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; Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +40 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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( Loading Loading @@ -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}; Loading @@ -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); Loading Loading @@ -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. Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +13 −5 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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 Loading Loading @@ -2613,8 +2617,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable float bottomAmount = getCurrentOverScrollAmount(false); if (velocityY < 0 && topAmount > 0) { setOwnScrollY(mOwnScrollY - (int) topAmount); if (!mShouldUseSplitNotificationShade) { mDontReportNextOverScroll = true; setOverScrollAmount(0, true, false); } mMaxOverScroll = Math.abs(velocityY) / 1000f * getRubberBandFactor(true /* onTop */) * mOverflingDistance + topAmount; } else if (velocityY > 0 && bottomAmount > 0) { Loading Loading @@ -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)); } Loading Loading @@ -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; Loading Loading @@ -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; Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +40 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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( Loading Loading @@ -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}; Loading @@ -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); Loading Loading @@ -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. Loading