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

Commit 48556f26 authored by William Xiao's avatar William Xiao Committed by Android (Google) Code Review
Browse files

Merge changes I92b9c220,I31a55ca1,I536a2e1e into main

* changes:
  Fix ShadeTouchHandler over the lock screen
  Use TouchMonitor for touch handling over hub
  Stop overlay touch handling when the bouncer or glanceable hub are visible over the dream
parents 2e086e36 86fa77ab
Loading
Loading
Loading
Loading
+18 −180
Original line number Diff line number Diff line
@@ -149,7 +149,6 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
                mUiEventLogger);

        when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
        when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
        when(mVelocityTrackerFactory.obtain()).thenReturn(mVelocityTracker);
        when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
@@ -193,11 +192,6 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
                        2)).isTrue();
    }

    private enum Direction {
        DOWN,
        UP,
    }

    @Test
    public void testSwipeUp_whenBouncerInitiallyShowing_reduceHeightWithExclusionRects() {
        mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion,
@@ -278,69 +272,11 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
    }

    /**
     * Makes sure swiping up when bouncer initially showing doesn't change the expansion amount.
     */
    @DisableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING)
    @Test
    public void testSwipeUp_whenBouncerInitiallyShowing_doesNotSetExpansion() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);

        mTouchHandler.onSessionStart(mTouchSession);
        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
        verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());

        final OnGestureListener gestureListener = gestureListenerCaptor.getValue();

        final float percent = .3f;
        final float distanceY = SCREEN_HEIGHT_PX * percent;

        // Swiping up near the top of the screen where the touch initiation region is.
        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, distanceY, 0);
        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, 0, 0);

        assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)).isTrue();

        verify(mScrimController, never()).expand(any());
    }

    /**
     * Makes sure swiping up when bouncer initially showing doesn't change the expansion amount.
     */
    @Test
    @EnableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING)
    public void testSwipeUp_whenBouncerInitiallyShowing_doesNotSetExpansion_directionFiltering() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);

        mTouchHandler.onSessionStart(mTouchSession);
        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
        verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());

        final OnGestureListener gestureListener = gestureListenerCaptor.getValue();

        final float percent = .3f;
        final float distanceY = SCREEN_HEIGHT_PX * percent;

        // Swiping up near the top of the screen where the touch initiation region is.
        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, distanceY, 0);
        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, 0, 0);

        assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)).isFalse();

        verify(mScrimController, never()).expand(any());
    }

    /**
     * Makes sure swiping down when bouncer initially hidden doesn't change the expansion amount.
     * Makes sure swiping down doesn't change the expansion amount.
     */
    @Test
    @DisableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING)
    public void testSwipeDown_whenBouncerInitiallyHidden_doesNotSetExpansion() {
    public void testSwipeDown_doesNotSetExpansion() {
        mTouchHandler.onSessionStart(mTouchSession);
        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
@@ -401,34 +337,8 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {

        final OnGestureListener gestureListener = gestureListenerCaptor.getValue();

        verifyScroll(.3f, Direction.UP, false, gestureListener);

        // Ensure that subsequent gestures are treated as expanding even if the bouncer state
        // changes.
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
        verifyScroll(.7f, Direction.UP, false, gestureListener);
    }

    /**
     * Makes sure the expansion amount is proportional to scroll.
     */
    @Test
    public void testSwipeDown_setsCorrectExpansionAmount() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);

        mTouchHandler.onSessionStart(mTouchSession);
        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
        verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());

        final OnGestureListener gestureListener = gestureListenerCaptor.getValue();

        verifyScroll(.3f, Direction.DOWN, true, gestureListener);

        // Ensure that subsequent gestures are treated as collapsing even if the bouncer state
        // changes.
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
        verifyScroll(.7f, Direction.DOWN, true, gestureListener);
        verifyScroll(.3f, gestureListener);
        verifyScroll(.7f, gestureListener);
    }

    /**
@@ -493,25 +403,24 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        verify(mCentralSurfaces, never()).awakenDreams();
    }

    private void verifyScroll(float percent, Direction direction,
            boolean isBouncerInitiallyShowing, GestureDetector.OnGestureListener gestureListener) {
    private void verifyScroll(float percent,
            OnGestureListener gestureListener) {
        final float distanceY = SCREEN_HEIGHT_PX * percent;

        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, direction == Direction.UP ? SCREEN_HEIGHT_PX : 0, 0);
                0, SCREEN_HEIGHT_PX, 0);
        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0);
                0, SCREEN_HEIGHT_PX - distanceY, 0);

        reset(mScrimController);
        assertThat(gestureListener.onScroll(event1, event2, 0,
                direction == Direction.UP ? distanceY : -distanceY))
                distanceY))
                .isTrue();

        // Ensure only called once
        verify(mScrimController).expand(any());

        final float expansion = isBouncerInitiallyShowing ? percent : 1 - percent;
        final float dragDownAmount = event2.getY() - event1.getY();
        final float expansion = 1 - percent;

        // Ensure correct expansion passed in.
        ShadeExpansionChangeEvent event =
@@ -529,7 +438,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        final float expansion = 1 - swipeUpPercentage;
        // The upward velocity is ignored.
        final float velocityY = -1;
        swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
        swipeToPosition(swipeUpPercentage, velocityY);

        verify(mValueAnimatorCreator).create(eq(expansion),
                eq(KeyguardBouncerConstants.EXPANSION_HIDDEN));
@@ -552,7 +461,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        final float expansion = 1 - swipeUpPercentage;
        // The downward velocity is ignored.
        final float velocityY = 1;
        swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
        swipeToPosition(swipeUpPercentage, velocityY);

        verify(mValueAnimatorCreator).create(eq(expansion),
                eq(KeyguardBouncerConstants.EXPANSION_VISIBLE));
@@ -572,57 +481,6 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_BOUNCER_FULLY_VISIBLE);
    }

    /**
     * Tests that ending a downward swipe above the set threshold will continue the expansion,
     * but will not trigger logging of the DREAM_SWIPED event.
     */
    @Test
    public void testSwipeDownPositionAboveThreshold_expandsBouncer_doesNotLog() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);

        final float swipeDownPercentage = .3f;
        // The downward velocity is ignored.
        final float velocityY = 1;
        swipeToPosition(swipeDownPercentage, Direction.DOWN, velocityY);

        verify(mValueAnimatorCreator).create(eq(swipeDownPercentage),
                eq(KeyguardBouncerConstants.EXPANSION_VISIBLE));
        verify(mValueAnimator, never()).addListener(any());

        verify(mFlingAnimationUtils).apply(eq(mValueAnimator),
                eq(SCREEN_HEIGHT_PX * swipeDownPercentage),
                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_VISIBLE),
                eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
        verify(mValueAnimator).start();
        verify(mUiEventLogger, never()).log(any());
    }

    /**
     * Tests that swiping down with a speed above the set threshold leads to bouncer collapsing
     * down.
     */
    @Test
    public void testSwipeDownVelocityAboveMin_collapsesBouncer() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
        when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn((float) 0);

        // The ending position above the set threshold is ignored.
        final float swipeDownPercentage = .3f;
        final float velocityY = 1;
        swipeToPosition(swipeDownPercentage, Direction.DOWN, velocityY);

        verify(mValueAnimatorCreator).create(eq(swipeDownPercentage),
                eq(KeyguardBouncerConstants.EXPANSION_HIDDEN));
        verify(mValueAnimator, never()).addListener(any());

        verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
                eq(SCREEN_HEIGHT_PX * swipeDownPercentage),
                eq(SCREEN_HEIGHT_PX * KeyguardBouncerConstants.EXPANSION_HIDDEN),
                eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
        verify(mValueAnimator).start();
        verify(mUiEventLogger, never()).log(any());
    }

    /**
     * Tests that swiping up with a speed above the set threshold will continue the expansion.
     */
@@ -634,7 +492,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        final float swipeUpPercentage = .3f;
        final float expansion = 1 - swipeUpPercentage;
        final float velocityY = -1;
        swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
        swipeToPosition(swipeUpPercentage, velocityY);

        verify(mValueAnimatorCreator).create(eq(expansion),
                eq(KeyguardBouncerConstants.EXPANSION_VISIBLE));
@@ -654,26 +512,6 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_BOUNCER_FULLY_VISIBLE);
    }

    /**
     * Ensures {@link CentralSurfaces}
     */
    @Test
    public void testInformBouncerShowingOnExpand() {
        swipeToPosition(1f, Direction.UP, 0);
    }

    /**
     * Ensures {@link CentralSurfaces}
     */
    @Test
    public void testInformBouncerHidingOnCollapse() {
        // Must swipe up to set initial state.
        swipeToPosition(1f, Direction.UP, 0);
        Mockito.clearInvocations(mCentralSurfaces);

        swipeToPosition(0f, Direction.DOWN, 0);
    }

    @Test
    public void testTouchSessionOnRemovedCalledTwice() {
        mTouchHandler.onSessionStart(mTouchSession);
@@ -684,7 +522,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        onRemovedCallbackCaptor.getValue().onRemoved();
    }

    private void swipeToPosition(float percent, Direction direction, float velocityY) {
    private void swipeToPosition(float percent, float velocityY) {
        Mockito.clearInvocations(mTouchSession);
        mTouchHandler.onSessionStart(mTouchSession);
        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
@@ -699,12 +537,12 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        final float distanceY = SCREEN_HEIGHT_PX * percent;

        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, direction == Direction.UP ? SCREEN_HEIGHT_PX : 0, 0);
                0, SCREEN_HEIGHT_PX, 0);
        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
                0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0);
                0, SCREEN_HEIGHT_PX - distanceY, 0);

        assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0,
                direction == Direction.UP ? distanceY : -distanceY))
                distanceY))
                .isTrue();

        final MotionEvent upEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP,
+63 −38
Original line number Diff line number Diff line
@@ -18,8 +18,10 @@ package com.android.systemui.ambient.touch;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.view.GestureDetector;
import android.view.MotionEvent;
@@ -28,7 +30,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.phone.CentralSurfaces;

@@ -36,6 +37,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -48,67 +50,90 @@ public class ShadeTouchHandlerTest extends SysuiTestCase {
    @Mock
    CentralSurfaces mCentralSurfaces;

    @Mock
    ShadeViewController mShadeViewController;

    @Mock
    TouchHandler.TouchSession mTouchSession;

    ShadeTouchHandler mTouchHandler;

    @Captor
    ArgumentCaptor<GestureDetector.OnGestureListener> mGestureListenerCaptor;
    @Captor
    ArgumentCaptor<InputChannelCompat.InputEventListener> mInputListenerCaptor;

    private static final int TOUCH_HEIGHT = 20;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mTouchHandler = new ShadeTouchHandler(Optional.of(mCentralSurfaces), mShadeViewController,
                TOUCH_HEIGHT);

        mTouchHandler = new ShadeTouchHandler(Optional.of(mCentralSurfaces), TOUCH_HEIGHT);
    }

    /**
     * Verify that touches aren't handled when the bouncer is showing.
     */
    // Verifies that a swipe down in the gesture region is captured by the shade touch handler.
    @Test
    public void testInactiveOnBouncer() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).pop();
    public void testSwipeDown_captured() {
        final boolean captured = swipe(Direction.DOWN);

        assertThat(captured).isTrue();
    }

    /**
     * Make sure {@link ShadeTouchHandler}
     */
    // Verifies that a swipe in the upward direction is not catpured.
    @Test
    public void testTouchPilferingOnScroll() {
        final MotionEvent motionEvent1 = Mockito.mock(MotionEvent.class);
        final MotionEvent motionEvent2 = Mockito.mock(MotionEvent.class);
    public void testSwipeUp_notCaptured() {
        final boolean captured = swipe(Direction.UP);

        final ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerArgumentCaptor =
                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
        // Motion events not captured as the swipe is going in the wrong direction.
        assertThat(captured).isFalse();
    }

        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).registerGestureListener(gestureListenerArgumentCaptor.capture());
    // Verifies that a swipe down forwards captured touches to the shade window for handling.
    @Test
    public void testSwipeDown_sentToShadeWindow() {
        swipe(Direction.DOWN);

        assertThat(gestureListenerArgumentCaptor.getValue()
                .onScroll(motionEvent1, motionEvent2, 1, 1))
                .isTrue();
        // Both motion events are sent for the shade window to process.
        verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any());
    }

    /**
     * Ensure touches are propagated to the {@link ShadeViewController}.
     */
    // Verifies that a swipe down is not forwarded to the shade window.
    @Test
    public void testEventPropagation() {
        final MotionEvent motionEvent = Mockito.mock(MotionEvent.class);
    public void testSwipeUp_touchesNotSent() {
        swipe(Direction.UP);

        final ArgumentCaptor<InputChannelCompat.InputEventListener>
                inputEventListenerArgumentCaptor =
                    ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class);
        // Motion events are not sent for the shade window to process as the swipe is going in the
        // wrong direction.
        verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any());
    }

    /**
     * Simulates a swipe in the given direction and returns true if the touch was intercepted by the
     * touch handler's gesture listener.
     * <p>
     * Swipe down starts from a Y coordinate of 0 and goes downward. Swipe up starts from the edge
     * of the gesture region, {@link #TOUCH_HEIGHT}, and goes upward to 0.
     */
    private boolean swipe(Direction direction) {
        Mockito.clearInvocations(mTouchSession);
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).registerInputListener(inputEventListenerArgumentCaptor.capture());
        inputEventListenerArgumentCaptor.getValue().onInputEvent(motionEvent);
        verify(mShadeViewController).handleExternalTouch(motionEvent);

        verify(mTouchSession).registerGestureListener(mGestureListenerCaptor.capture());
        verify(mTouchSession).registerInputListener(mInputListenerCaptor.capture());

        final float startY = direction == Direction.UP ? TOUCH_HEIGHT : 0;
        final float endY = direction == Direction.UP ? 0 : TOUCH_HEIGHT;

        // Send touches to the input and gesture listener.
        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, startY, 0);
        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, endY, 0);
        mInputListenerCaptor.getValue().onInputEvent(event1);
        mInputListenerCaptor.getValue().onInputEvent(event2);
        final boolean captured = mGestureListenerCaptor.getValue().onScroll(event1, event2, 0,
                startY - endY);

        return captured;
    }

    private enum Direction {
        DOWN, UP,
    }
}
+291 −77

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ public class CommunalTouchHandlerTest extends SysuiTestCase {
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).registerInputListener(inputEventListenerArgumentCaptor.capture());
        inputEventListenerArgumentCaptor.getValue().onInputEvent(motionEvent);
        verify(mCentralSurfaces).handleDreamTouch(motionEvent);
        verify(mCentralSurfaces).handleExternalShadeWindowTouch(motionEvent);
    }

    @Test
+18 −38
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import com.android.internal.logging.UiEvent;
@@ -94,13 +95,11 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
    private Boolean mCapture;
    private Boolean mExpanded;

    private boolean mBouncerInitiallyShowing;

    private TouchSession mTouchSession;

    private ValueAnimatorCreator mValueAnimatorCreator;
    private final ValueAnimatorCreator mValueAnimatorCreator;

    private VelocityTrackerFactory mVelocityTrackerFactory;
    private final VelocityTrackerFactory mVelocityTrackerFactory;

    private final UiEventLogger mUiEventLogger;

@@ -118,17 +117,12 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
    private final GestureDetector.OnGestureListener mOnGestureListener =
            new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                public boolean onScroll(MotionEvent e1, @NonNull MotionEvent e2, float distanceX,
                        float distanceY) {
                    if (mCapture == null) {
                        mBouncerInitiallyShowing = mCentralSurfaces
                                .map(CentralSurfaces::isBouncerShowing)
                                .orElse(false);

                        if (Flags.dreamOverlayBouncerSwipeDirectionFiltering()) {
                            mCapture = Math.abs(distanceY) > Math.abs(distanceX)
                                    && ((distanceY < 0 && mBouncerInitiallyShowing)
                                    || (distanceY > 0 && !mBouncerInitiallyShowing));
                                    && distanceY > 0;
                        } else {
                            // If the user scrolling favors a vertical direction, begin capturing
                            // scrolls.
@@ -146,13 +140,8 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
                        return false;
                    }

                    // Don't set expansion for downward scroll when the bouncer is hidden.
                    if (!mBouncerInitiallyShowing && (e1.getY() < e2.getY())) {
                        return true;
                    }

                    // Don't set expansion for upward scroll when the bouncer is shown.
                    if (mBouncerInitiallyShowing && (e1.getY() > e2.getY())) {
                    // Don't set expansion for downward scroll.
                    if (e1.getY() < e2.getY()) {
                        return true;
                    }

@@ -176,8 +165,7 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
                    final float dragDownAmount = e2.getY() - e1.getY();
                    final float screenTravelPercentage = Math.abs(e1.getY() - e2.getY())
                            / mTouchSession.getBounds().height();
                    setPanelExpansion(mBouncerInitiallyShowing
                            ? screenTravelPercentage : 1 - screenTravelPercentage);
                    setPanelExpansion(1 - screenTravelPercentage);
                    return true;
                }
            };
@@ -247,17 +235,13 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
    public void getTouchInitiationRegion(Rect bounds, Region region, Rect exclusionRect) {
        final int width = bounds.width();
        final int height = bounds.height();
        final float minBouncerHeight = height * mMinBouncerZoneScreenPercentage;
        final int minAllowableBottom = Math.round(height * (1 - mMinBouncerZoneScreenPercentage));

        final boolean isBouncerShowing =
                mCentralSurfaces.map(CentralSurfaces::isBouncerShowing).orElse(false);
        final Rect normalRegion = isBouncerShowing
                ? new Rect(0, 0, width, Math.round(height * mBouncerZoneScreenPercentage))
                : new Rect(0, Math.round(height * (1 - mBouncerZoneScreenPercentage)),
        final Rect normalRegion = new Rect(0,
                Math.round(height * (1 - mBouncerZoneScreenPercentage)),
                width, height);

        if (!isBouncerShowing && exclusionRect != null) {
        if (exclusionRect != null) {
            int lowestBottom = Math.min(Math.max(0, exclusionRect.bottom), minAllowableBottom);
            normalRegion.top = Math.max(normalRegion.top, lowestBottom);
        }
@@ -322,8 +306,7 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
                        : KeyguardBouncerConstants.EXPANSION_HIDDEN;

                // Log the swiping up to show Bouncer event.
                if (!mBouncerInitiallyShowing
                        && expansion == KeyguardBouncerConstants.EXPANSION_VISIBLE) {
                if (expansion == KeyguardBouncerConstants.EXPANSION_VISIBLE) {
                    mUiEventLogger.log(DreamEvent.DREAM_SWIPED);
                }

@@ -335,17 +318,15 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
        }
    }

    private ValueAnimator createExpansionAnimator(float targetExpansion, float expansionHeight) {
    private ValueAnimator createExpansionAnimator(float targetExpansion) {
        final ValueAnimator animator =
                mValueAnimatorCreator.create(mCurrentExpansion, targetExpansion);
        animator.addUpdateListener(
                animation -> {
                    float expansionFraction = (float) animation.getAnimatedValue();
                    float dragDownAmount = expansionFraction * expansionHeight;
                    setPanelExpansion(expansionFraction);
                });
        if (!mBouncerInitiallyShowing
                && targetExpansion == KeyguardBouncerConstants.EXPANSION_VISIBLE) {
        if (targetExpansion == KeyguardBouncerConstants.EXPANSION_VISIBLE) {
            animator.addListener(
                    new AnimatorListenerAdapter() {
                        @Override
@@ -381,8 +362,7 @@ public class BouncerSwipeTouchHandler implements TouchHandler {
        final float viewHeight = mTouchSession.getBounds().height();
        final float currentHeight = viewHeight * mCurrentExpansion;
        final float targetHeight = viewHeight * expansion;
        final float expansionHeight = targetHeight - currentHeight;
        final ValueAnimator animator = createExpansionAnimator(expansion, expansionHeight);
        final ValueAnimator animator = createExpansionAnimator(expansion);
        if (expansion == KeyguardBouncerConstants.EXPANSION_HIDDEN) {
            // Hides the bouncer, i.e., fully expands the space above the bouncer.
            mFlingAnimationUtilsClosing.apply(animator, currentHeight, targetHeight, velocity,
Loading