Only detect swipe directions that lead to new states

This cleans up the code and ensures that the current state animation
is always initialized when we get drag events.

Also log when we pass through states.

Bug: 78017680
Change-Id: I54ab42923ed539940ea708973ad65f5793669c11
This commit is contained in:
Tony Wickham 2018-04-24 13:42:59 -07:00
parent f325b19de3
commit 52240a3aa0
5 changed files with 72 additions and 52 deletions

View File

@ -11,6 +11,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.util.SysuiEventLogger;
@ -38,17 +39,17 @@ public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchContro
return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
return SwipeDetector.DIRECTION_BOTH;
}
@Override
protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
boolean draggingFromNav = mLauncher.getDeviceProfile().isSeascape() != isDragTowardPositive;
return draggingFromNav ? OVERVIEW : NORMAL;
}
@Override
protected int getLogContainerTypeForNormalState() {
return LauncherLogProto.ContainerType.NAVBAR;
}
@Override
protected float getShiftRange() {
return mLauncher.getDragLayer().getWidth();

View File

@ -24,6 +24,7 @@ import android.view.MotionEvent;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.views.RecentsView;
@ -72,4 +73,8 @@ public class OverviewToAllAppsTouchController extends PortraitStatesTouchControl
return fromState;
}
@Override
protected int getLogContainerTypeForNormalState() {
return LauncherLogProto.ContainerType.WORKSPACE;
}
}

View File

@ -124,26 +124,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
return true;
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
final int directionsToDetectScroll;
if (mLauncher.isInState(ALL_APPS)) {
directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
mStartContainerType = ContainerType.ALLAPPS;
} else if (mLauncher.isInState(NORMAL)) {
directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
mStartContainerType = ContainerType.HOTSEAT;
} else if (mLauncher.isInState(OVERVIEW)) {
boolean canSwipeDownFromOverview = getTargetState(OVERVIEW, false) != OVERVIEW;
directionsToDetectScroll = canSwipeDownFromOverview ? SwipeDetector.DIRECTION_BOTH
: SwipeDetector.DIRECTION_POSITIVE;
mStartContainerType = ContainerType.TASKSWITCHER;
} else {
return 0;
}
return directionsToDetectScroll;
}
@Override
protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
if (fromState == ALL_APPS && !isDragTowardPositive) {
@ -152,12 +132,17 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
mLauncher.getStateManager().getLastState() : NORMAL;
} else if (fromState == OVERVIEW) {
return isDragTowardPositive ? ALL_APPS : NORMAL;
} else if (isDragTowardPositive) {
} else if (fromState == NORMAL && isDragTowardPositive) {
return TouchInteractionService.isConnected() ? OVERVIEW : ALL_APPS;
}
return fromState;
}
@Override
protected int getLogContainerTypeForNormalState() {
return ContainerType.HOTSEAT;
}
private AnimatorSetBuilder getNormalToOverviewAnimation() {
mAllAppsInterpolatorWrapper.baseInterpolator = mAllAppsDampedInterpolator;

View File

@ -15,6 +15,9 @@
*/
package com.android.launcher3.touch;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
@ -27,6 +30,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.TouchController;
@ -65,12 +69,6 @@ public abstract class AbstractStateChangeTouchController
protected abstract boolean canInterceptTouch(MotionEvent ev);
/**
* Initializes the {@code mFromState} and {@code mToState} and swipe direction to use for
* the detector. In case of disabling swipe, return 0.
*/
protected abstract int getSwipeDirection(MotionEvent ev);
@Override
public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
@ -94,7 +92,7 @@ public abstract class AbstractStateChangeTouchController
ignoreSlopWhenSettling = true;
}
} else {
directionsToDetectScroll = getSwipeDirection(ev);
directionsToDetectScroll = getSwipeDirection();
if (directionsToDetectScroll == 0) {
mNoIntercept = true;
return false;
@ -112,6 +110,18 @@ public abstract class AbstractStateChangeTouchController
return mDetector.isDraggingOrSettling();
}
private int getSwipeDirection() {
LauncherState fromState = mLauncher.getStateManager().getState();
int swipeDirection = 0;
if (getTargetState(fromState, true /* isDragTowardPositive */) != fromState) {
swipeDirection |= SwipeDetector.DIRECTION_POSITIVE;
}
if (getTargetState(fromState, false /* isDragTowardPositive */) != fromState) {
swipeDirection |= SwipeDetector.DIRECTION_NEGATIVE;
}
return swipeDirection;
}
@Override
public final boolean onControllerTouchEvent(MotionEvent ev) {
return mDetector.onTouchEvent(ev);
@ -130,6 +140,11 @@ public abstract class AbstractStateChangeTouchController
protected abstract float initCurrentAnimation();
/**
* Returns the container that the touch started from when leaving NORMAL state.
*/
protected abstract int getLogContainerTypeForNormalState();
private boolean reinitCurrentAnimation(boolean reachedToState, boolean isDragTowardPositive) {
LauncherState newFromState = mFromState == null ? mLauncher.getStateManager().getState()
: reachedToState ? mToState : mFromState;
@ -139,6 +154,17 @@ public abstract class AbstractStateChangeTouchController
return false;
}
if (reachedToState) {
logReachedState(Touch.SWIPE);
}
if (newFromState == ALL_APPS) {
mStartContainerType = ContainerType.ALLAPPS;
} else if (newFromState == NORMAL) {
mStartContainerType = getLogContainerTypeForNormalState();
} else if (newFromState == OVERVIEW){
mStartContainerType = ContainerType.TASKSWITCHER;
}
mFromState = newFromState;
mToState = newToState;
@ -261,18 +287,22 @@ public abstract class AbstractStateChangeTouchController
}
if (shouldGoToTargetState) {
if (targetState != mFromState) {
// Transition complete. log the action
mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
getDirectionForLog(),
mStartContainerType,
mFromState.containerType,
mToState.containerType,
mLauncher.getWorkspace().getCurrentPage());
logReachedState(logAction);
}
mLauncher.getStateManager().goToState(targetState, false /* animated */);
}
}
private void logReachedState(int logAction) {
// Transition complete. log the action
mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
getDirectionForLog(),
mStartContainerType,
mFromState.containerType,
mToState.containerType,
mLauncher.getWorkspace().getCurrentPage());
}
protected void clearState() {
mCurrentAnimation = null;
mDetector.finishedScrolling();

View File

@ -17,12 +17,17 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
*/
public class AllAppsSwipeController extends AbstractStateChangeTouchController {
private MotionEvent mTouchDownEvent;
public AllAppsSwipeController(Launcher l) {
super(l, SwipeDetector.VERTICAL);
}
@Override
protected boolean canInterceptTouch(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mTouchDownEvent = ev;
}
if (mCurrentAnimation != null) {
// If we are already animating from a previous state, we can intercept.
return true;
@ -40,18 +45,6 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
return true;
}
@Override
protected int getSwipeDirection(MotionEvent ev) {
if (mLauncher.isInState(ALL_APPS)) {
mStartContainerType = ContainerType.ALLAPPS;
return SwipeDetector.DIRECTION_NEGATIVE;
} else {
mStartContainerType = mLauncher.getDragLayer().isEventOverHotseat(ev) ?
ContainerType.HOTSEAT : ContainerType.WORKSPACE;
return SwipeDetector.DIRECTION_POSITIVE;
}
}
@Override
protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
if (fromState == NORMAL && isDragTowardPositive) {
@ -62,6 +55,12 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
return fromState;
}
@Override
protected int getLogContainerTypeForNormalState() {
return mLauncher.getDragLayer().isEventOverHotseat(mTouchDownEvent) ?
ContainerType.HOTSEAT : ContainerType.WORKSPACE;
}
@Override
protected float initCurrentAnimation() {
float range = getShiftRange();