Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 245cd0fe authored by Johannes Gallmann's avatar Johannes Gallmann Committed by Automerger Merge Worker
Browse files

Merge "Add overscroll effect to top of split shade" into tm-qpr-dev am: b5ff8518 am: 045eaa39

parents 7585ca3c 045eaa39
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -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);
                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;
+40 −3
Original line number Diff line number Diff line
@@ -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.