Store initial bouncer showing state.

This changelist keeps track of the initial bouncer showing state when
scrolling begins on the bouncer. This ensures the value does not change
mid scroll.

This changelist also cleans up session callbacks. onSessionEnd had
migrated to be a callback on the handler to a registered callback on
the session.

Bug: 223472045
Test: BouncerSwipeTouchHandlerTest DreamOverlayTouchMonitorTest
Change-Id: Ib2c295ce8f27d0f40f33039a71ec39b52ef96ddb
This commit is contained in:
Bryce Lee
2022-03-08 18:12:06 -08:00
parent 74807869b8
commit 39ce1a56dd
5 changed files with 77 additions and 32 deletions

View File

@@ -82,6 +82,8 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler {
private Boolean mCapture;
private boolean mBouncerInitiallyShowing;
private TouchSession mTouchSession;
private ValueAnimatorCreator mValueAnimatorCreator;
@@ -97,6 +99,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler {
// If the user scrolling favors a vertical direction, begin capturing
// scrolls.
mCapture = Math.abs(distanceY) > Math.abs(distanceX);
mBouncerInitiallyShowing = mCentralSurfaces.isBouncerShowing();
if (mCapture) {
// Since the user is dragging the bouncer up, set scrimmed to false.
@@ -115,7 +118,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler {
// (0).
final float screenTravelPercentage =
Math.abs((e1.getY() - e2.getY()) / mCentralSurfaces.getDisplayHeight());
setPanelExpansion(mCentralSurfaces.isBouncerShowing()
setPanelExpansion(mBouncerInitiallyShowing
? screenTravelPercentage : 1 - screenTravelPercentage);
return true;
}
@@ -174,18 +177,18 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler {
mTouchSession = session;
mVelocityTracker.clear();
mNotificationShadeWindowController.setForcePluginOpen(true, this);
session.registerCallback(() -> {
mVelocityTracker.recycle();
mCapture = null;
mNotificationShadeWindowController.setForcePluginOpen(false, this);
});
session.registerGestureListener(mOnGestureListener);
session.registerInputListener(ev -> onMotionEvent(ev));
}
@Override
public void onSessionEnd(TouchSession session) {
mVelocityTracker.recycle();
mCapture = null;
mNotificationShadeWindowController.setForcePluginOpen(false, this);
}
private void onMotionEvent(InputEvent event) {
if (!(event instanceof MotionEvent)) {
Log.e(TAG, "non MotionEvent received:" + event);

View File

@@ -96,11 +96,4 @@ public interface DreamTouchHandler {
* @param session
*/
void onSessionStart(TouchSession session);
/**
* Invoked when a session has ended. This will be invoked for every session completion, even
* those that are removed through {@link TouchSession#pop()}.
* @param session
*/
default void onSessionEnd(TouchSession session) { }
}

View File

@@ -127,11 +127,4 @@ public class HideComplicationTouchHandler implements DreamTouchHandler {
}
});
}
@Override
public void onSessionEnd(TouchSession session) {
if (DEBUG) {
Log.d(TAG, "onSessionEnd");
}
}
}

View File

@@ -31,6 +31,7 @@ import android.graphics.Region;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -111,6 +112,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
mFlingAnimationUtilsClosing,
TOUCH_REGION);
when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
when(mCentralSurfaces.getDisplayHeight()).thenReturn((float) SCREEN_HEIGHT_PX);
when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
@@ -162,24 +164,58 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
final float scrollAmount = .3f;
final float distanceY = SCREEN_HEIGHT_PX * scrollAmount;
final OnGestureListener gestureListener = gestureListenerCaptor.getValue();
when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
verifyScroll(.3f, Direction.UP, true, gestureListener);
// Ensure that subsequent gestures are treated as expanding even if the bouncer state
// changes.
when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
verifyScroll(.7f, Direction.UP, true, gestureListener);
}
/**
* Makes sure collapse amount is proportional to scroll.
*/
@Test
public void testCollapseAmount() {
mTouchHandler.onSessionStart(mTouchSession);
ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
final OnGestureListener gestureListener = gestureListenerCaptor.getValue();
when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
verifyScroll(.3f, Direction.DOWN, false, gestureListener);
// Ensure that subsequent gestures are treated as collapsing even if the bouncer state
// changes.
when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
verifyScroll(.7f, Direction.DOWN, false, gestureListener);
}
private enum Direction {
DOWN,
UP,
}
private void verifyScroll(float percent, Direction direction, boolean expanding,
android.view.GestureDetector.OnGestureListener gestureListener) {
final float distanceY = SCREEN_HEIGHT_PX * percent;
final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
0, SCREEN_HEIGHT_PX, 0);
0, direction == Direction.UP ? SCREEN_HEIGHT_PX : 0, 0);
final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
0, SCREEN_HEIGHT_PX - distanceY, 0);
0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0);
assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0, distanceY))
assertThat(gestureListener.onScroll(event1, event2, 0, distanceY))
.isTrue();
// Ensure only called once
verify(mStatusBarKeyguardViewManager)
.onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
// Ensure correct expansion passed in.
verify(mStatusBarKeyguardViewManager)
.onPanelExpansionChanged(eq(1 - scrollAmount), eq(false), eq(true));
.onPanelExpansionChanged(
eq(expanding ? 1 - percent : percent), eq(false), eq(true));
}
/**

View File

@@ -344,6 +344,26 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
verify(frontEventListener, never()).onInputEvent(any());
}
@Test
public void testPop() {
final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
final DreamTouchHandler.TouchSession.Callback callback =
Mockito.mock(DreamTouchHandler.TouchSession.Callback.class);
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
final DreamTouchHandler.TouchSession session = captureSession(touchHandler);
session.registerCallback(callback);
session.pop();
environment.executeAll();
verify(callback).onRemoved();
}
@Test
public void testPause() {
final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);