Merge "Fix BaseSwipeDetector#setState() called inside another setState()" into ub-launcher3-master
This commit is contained in:
commit
2abd13a80b
|
@ -508,7 +508,7 @@ public abstract class AbstractStateChangeTouchController
|
|||
mAtomicComponentsController.getAnimationPlayer().end();
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
cancelAnimationControllers();
|
||||
clearState();
|
||||
boolean shouldGoToTargetState = true;
|
||||
if (mPendingAnimation != null) {
|
||||
boolean reachedTarget = mToState == targetState;
|
||||
|
@ -546,13 +546,13 @@ public abstract class AbstractStateChangeTouchController
|
|||
mAtomicAnim = null;
|
||||
}
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
mDetector.finishedScrolling();
|
||||
mDetector.setDetectableScrollConditions(0, false);
|
||||
}
|
||||
|
||||
private void cancelAnimationControllers() {
|
||||
mCurrentAnimation = null;
|
||||
cancelAtomicComponentsController();
|
||||
mDetector.finishedScrolling();
|
||||
mDetector.setDetectableScrollConditions(0, false);
|
||||
}
|
||||
|
||||
private void cancelAtomicComponentsController() {
|
||||
|
|
|
@ -24,6 +24,10 @@ import android.view.VelocityTracker;
|
|||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* Scroll/drag/swipe gesture detector.
|
||||
|
@ -49,13 +53,15 @@ public abstract class BaseSwipeDetector {
|
|||
protected final boolean mIsRtl;
|
||||
protected final float mTouchSlop;
|
||||
protected final float mMaxVelocity;
|
||||
private final Queue<Runnable> mSetStateQueue = new LinkedList<>();
|
||||
|
||||
private int mActivePointerId = INVALID_POINTER_ID;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
private PointF mLastDisplacement = new PointF();
|
||||
private PointF mDisplacement = new PointF();
|
||||
protected PointF mSubtractDisplacement = new PointF();
|
||||
private ScrollState mState = ScrollState.IDLE;
|
||||
@VisibleForTesting ScrollState mState = ScrollState.IDLE;
|
||||
private boolean mIsSettingState;
|
||||
|
||||
protected boolean mIgnoreSlopWhenSettling;
|
||||
|
||||
|
@ -195,6 +201,12 @@ public abstract class BaseSwipeDetector {
|
|||
// SETTLING -> (View settled) -> IDLE
|
||||
|
||||
private void setState(ScrollState newState) {
|
||||
if (mIsSettingState) {
|
||||
mSetStateQueue.add(() -> setState(newState));
|
||||
return;
|
||||
}
|
||||
mIsSettingState = true;
|
||||
|
||||
if (DBG) {
|
||||
Log.d(TAG, "setState:" + mState + "->" + newState);
|
||||
}
|
||||
|
@ -212,6 +224,10 @@ public abstract class BaseSwipeDetector {
|
|||
}
|
||||
|
||||
mState = newState;
|
||||
mIsSettingState = false;
|
||||
if (!mSetStateQueue.isEmpty()) {
|
||||
mSetStateQueue.remove().run();
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeDragging() {
|
||||
|
|
|
@ -21,9 +21,11 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_POSI
|
|||
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
|
||||
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyFloat;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
@ -168,4 +170,21 @@ public class SingleAxisSwipeDetectorTest {
|
|||
// TODO: actually calculate the following parameters and do exact value checks.
|
||||
verify(mMockListener).onDragEnd(anyFloat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterleavedSetState() {
|
||||
doAnswer(invocationOnMock -> {
|
||||
// Sets state to IDLE. (Normally onDragEnd() will have state SETTLING.)
|
||||
mDetector.finishedScrolling();
|
||||
return null;
|
||||
}).when(mMockListener).onDragEnd(anyFloat());
|
||||
|
||||
mGenerator.put(0, 100, 100);
|
||||
mGenerator.move(0, 100, 100 + mTouchSlop);
|
||||
mGenerator.move(0, 100, 100 + mTouchSlop * 2);
|
||||
mGenerator.lift(0);
|
||||
verify(mMockListener).onDragEnd(anyFloat());
|
||||
assertTrue("SwipeDetector should be IDLE but was " + mDetector.mState,
|
||||
mDetector.isIdleState());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue