Fix BaseSwipeDetector#setState() called inside another setState()
Clients of BaseSwipeDetector are required to call finishedScrolling(), which calls setState(IDLE). An obvious place to call this is in onDragEnd(), which itself is called from a setState(SETTLING). If the client does this, then the SETTLING state actually clobbers the IDLE state, leading to undefined behavior. The reason we don't see this in practice is because we usually call finishedScrolling() after an animation from onDragEnd() instead of calling it immediately. To fix this, we add a simple queue such that any calls to setState() while one is in progress have to wait and are executed in turn. This ensures we get all the proper state callbacks and end in the correct one. Also fix an incorrect call in AbstractStateChangeTouchController which was masked by this bug. We were calling setState(IDLE) in onDragStart(), which only worked because the original setState(DRAGGING) incorrectly clobbered this. Now we only setState(IDLE) (via finishedScrolling()) when we fully clear the state, i.e. when the interaction is finished. Test: added testInterleavedSetState Bug: 141939911 Change-Id: Iae630ee7101921b57a85d40646468cf19f59b674
Loading
Please register or sign in to comment