Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java +38 −31 Original line number Diff line number Diff line Loading @@ -685,47 +685,54 @@ class DividerPresenter implements View.OnTouchListener { ? taskBounds.width() - mProperties.mDividerWidthPx : taskBounds.height() - mProperties.mDividerWidthPx; if (isDraggingToFullscreenAllowed(mProperties.mDividerAttributes)) { final float displayDensity = getDisplayDensity(); return dividerPositionWithDraggingToFullscreenAllowed( final boolean isDraggingToFullscreenAllowed = isDraggingToFullscreenAllowed(mProperties.mDividerAttributes); return dividerPositionWithPositionOptions( dividerPosition, minPosition, maxPosition, fullyExpandedPosition, velocity, displayDensity); } return Math.clamp(dividerPosition, minPosition, maxPosition); displayDensity, isDraggingToFullscreenAllowed); } /** * Returns the divider position given a set of position options. A snap algorithm is used to * adjust the ending position to either fully expand one container or move the divider back to * the specified min/max ratio depending on the dragging velocity. * Returns the divider position given a set of position options. A snap algorithm can adjust * the ending position to either fully expand one container or move the divider back to * the specified min/max ratio depending on the dragging velocity and if dragging to fullscreen * is allowed. */ @VisibleForTesting static int dividerPositionWithDraggingToFullscreenAllowed(int dividerPosition, int minPosition, int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity) { static int dividerPositionWithPositionOptions(int dividerPosition, int minPosition, int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity, boolean isDraggingToFullscreenAllowed) { if (isDraggingToFullscreenAllowed) { final float minDismissVelocityPxPerSecond = MIN_DISMISS_VELOCITY_DP_PER_SECOND * displayDensity; final float minFlingVelocityPxPerSecond = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity; if (dividerPosition < minPosition && velocity < -minDismissVelocityPxPerSecond) { return 0; } if (dividerPosition > maxPosition && velocity > minDismissVelocityPxPerSecond) { return fullyExpandedPosition; } if (Math.abs(velocity) < minFlingVelocityPxPerSecond) { if (dividerPosition >= minPosition && dividerPosition <= maxPosition) { return dividerPosition; } final int[] snapPositions = {0, minPosition, maxPosition, fullyExpandedPosition}; return snap(dividerPosition, snapPositions); } final float minFlingVelocityPxPerSecond = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity; if (Math.abs(velocity) >= minFlingVelocityPxPerSecond) { return dividerPositionForFling( dividerPosition, minPosition, maxPosition, velocity); } if (dividerPosition >= minPosition && dividerPosition <= maxPosition) { return dividerPosition; } return snap( dividerPosition, isDraggingToFullscreenAllowed ? new int[] {0, minPosition, maxPosition, fullyExpandedPosition} : new int[] {minPosition, maxPosition}); } /** * Returns the closest position that is in the fling direction. Loading libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java +151 −18 Original line number Diff line number Diff line Loading @@ -660,108 +660,241 @@ public class DividerPresenterTest { // Divider position is less than minPosition and the velocity is enough to be dismissed assertEquals( 0, // Closed position DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 10 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, -dismissVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is greater than maxPosition and the velocity is enough to be dismissed assertEquals( 1200, // Fully expanded position DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 1000 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, dismissVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is returned when the velocity is not fast enough for fling and is in // between minPosition and maxPosition assertEquals( 500, // dividerPosition is not snapped DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and larger // than maxPosition assertEquals( 900, // Closest position is maxPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 950 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and smaller // than minPosition assertEquals( 30, // Closest position is minPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 20 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to maxPosition bounds and the velocity is enough for // backward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 2200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to maxPosition bounds and the velocity is enough // for backward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to minPosition bounds and the velocity is enough for // forward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to minPosition bounds and the velocity is enough // for forward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); } @Test public void testDividerPositionWithDraggingToFullscreenNotAllowed() { final float displayDensity = 600F; final float nonFlingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity - 10f; final float flingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity + 10f; // Divider position is returned when the velocity is not fast enough for fling and is in // between minPosition and maxPosition assertEquals( 500, // dividerPosition is not snapped DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and larger // than maxPosition assertEquals( 900, // Closest position is maxPosition DividerPresenter.dividerPositionWithPositionOptions( 950 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and smaller // than minPosition assertEquals( 30, // Closest position is minPosition DividerPresenter.dividerPositionWithPositionOptions( 20 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and at the // closed position assertEquals( 30, // Closest position is minPosition DividerPresenter.dividerPositionWithPositionOptions( 0 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and at the // fully expanded position assertEquals( 900, // Closest position is maxPosition DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to maxPosition bounds and the velocity is enough for // backward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithPositionOptions( 2200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to maxPosition bounds and the velocity is enough // for backward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to minPosition bounds and the velocity is enough for // forward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to minPosition bounds and the velocity is enough // for forward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); } private TaskFragmentContainer createMockTaskFragmentContainer( Loading Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java +38 −31 Original line number Diff line number Diff line Loading @@ -685,47 +685,54 @@ class DividerPresenter implements View.OnTouchListener { ? taskBounds.width() - mProperties.mDividerWidthPx : taskBounds.height() - mProperties.mDividerWidthPx; if (isDraggingToFullscreenAllowed(mProperties.mDividerAttributes)) { final float displayDensity = getDisplayDensity(); return dividerPositionWithDraggingToFullscreenAllowed( final boolean isDraggingToFullscreenAllowed = isDraggingToFullscreenAllowed(mProperties.mDividerAttributes); return dividerPositionWithPositionOptions( dividerPosition, minPosition, maxPosition, fullyExpandedPosition, velocity, displayDensity); } return Math.clamp(dividerPosition, minPosition, maxPosition); displayDensity, isDraggingToFullscreenAllowed); } /** * Returns the divider position given a set of position options. A snap algorithm is used to * adjust the ending position to either fully expand one container or move the divider back to * the specified min/max ratio depending on the dragging velocity. * Returns the divider position given a set of position options. A snap algorithm can adjust * the ending position to either fully expand one container or move the divider back to * the specified min/max ratio depending on the dragging velocity and if dragging to fullscreen * is allowed. */ @VisibleForTesting static int dividerPositionWithDraggingToFullscreenAllowed(int dividerPosition, int minPosition, int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity) { static int dividerPositionWithPositionOptions(int dividerPosition, int minPosition, int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity, boolean isDraggingToFullscreenAllowed) { if (isDraggingToFullscreenAllowed) { final float minDismissVelocityPxPerSecond = MIN_DISMISS_VELOCITY_DP_PER_SECOND * displayDensity; final float minFlingVelocityPxPerSecond = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity; if (dividerPosition < minPosition && velocity < -minDismissVelocityPxPerSecond) { return 0; } if (dividerPosition > maxPosition && velocity > minDismissVelocityPxPerSecond) { return fullyExpandedPosition; } if (Math.abs(velocity) < minFlingVelocityPxPerSecond) { if (dividerPosition >= minPosition && dividerPosition <= maxPosition) { return dividerPosition; } final int[] snapPositions = {0, minPosition, maxPosition, fullyExpandedPosition}; return snap(dividerPosition, snapPositions); } final float minFlingVelocityPxPerSecond = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity; if (Math.abs(velocity) >= minFlingVelocityPxPerSecond) { return dividerPositionForFling( dividerPosition, minPosition, maxPosition, velocity); } if (dividerPosition >= minPosition && dividerPosition <= maxPosition) { return dividerPosition; } return snap( dividerPosition, isDraggingToFullscreenAllowed ? new int[] {0, minPosition, maxPosition, fullyExpandedPosition} : new int[] {minPosition, maxPosition}); } /** * Returns the closest position that is in the fling direction. Loading
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java +151 −18 Original line number Diff line number Diff line Loading @@ -660,108 +660,241 @@ public class DividerPresenterTest { // Divider position is less than minPosition and the velocity is enough to be dismissed assertEquals( 0, // Closed position DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 10 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, -dismissVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is greater than maxPosition and the velocity is enough to be dismissed assertEquals( 1200, // Fully expanded position DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 1000 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, dismissVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is returned when the velocity is not fast enough for fling and is in // between minPosition and maxPosition assertEquals( 500, // dividerPosition is not snapped DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and larger // than maxPosition assertEquals( 900, // Closest position is maxPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 950 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and smaller // than minPosition assertEquals( 30, // Closest position is minPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 20 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to maxPosition bounds and the velocity is enough for // backward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 2200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to maxPosition bounds and the velocity is enough // for backward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to minPosition bounds and the velocity is enough for // forward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to minPosition bounds and the velocity is enough // for forward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed( DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity)); displayDensity, true /* isDraggingToFullscreenAllowed */)); } @Test public void testDividerPositionWithDraggingToFullscreenNotAllowed() { final float displayDensity = 600F; final float nonFlingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity - 10f; final float flingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity + 10f; // Divider position is returned when the velocity is not fast enough for fling and is in // between minPosition and maxPosition assertEquals( 500, // dividerPosition is not snapped DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and larger // than maxPosition assertEquals( 900, // Closest position is maxPosition DividerPresenter.dividerPositionWithPositionOptions( 950 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and smaller // than minPosition assertEquals( 30, // Closest position is minPosition DividerPresenter.dividerPositionWithPositionOptions( 20 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and at the // closed position assertEquals( 30, // Closest position is minPosition DividerPresenter.dividerPositionWithPositionOptions( 0 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is snapped when the velocity is not fast enough for fling and at the // fully expanded position assertEquals( 900, // Closest position is maxPosition DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 30 /* minPosition */, 900 /* maxPosition */, 1200 /* fullyExpandedPosition */, nonFlingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to maxPosition bounds and the velocity is enough for // backward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithPositionOptions( 2200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to maxPosition bounds and the velocity is enough // for backward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, -flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is in the closed to minPosition bounds and the velocity is enough for // forward fling assertEquals( 1000, // minPosition DividerPresenter.dividerPositionWithPositionOptions( 500 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); // Divider position is not in the closed to minPosition bounds and the velocity is enough // for forward fling assertEquals( 2000, // maxPosition DividerPresenter.dividerPositionWithPositionOptions( 1200 /* dividerPosition */, 1000 /* minPosition */, 2000 /* maxPosition */, 2500 /* fullyExpandedPosition */, flingVelocity, displayDensity, false /* isDraggingToFullscreenAllowed */)); } private TaskFragmentContainer createMockTaskFragmentContainer( Loading