mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 03:08:19 +00:00
- The failure is not reproducible locally, thus requires adding logs and check ATP result - Removed some redundant logs - Changed to log at VERBOSE - Added extensive logging to all visibility/enable/alpha setter of ActionsView Bug: 193125090 Test: Manual Change-Id: I5b449a7f86ea4cef65e0e46de4b389deef9f53f3
448 lines
21 KiB
Java
448 lines
21 KiB
Java
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.android.launcher3.uioverrides.touchcontrollers;
|
|
|
|
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
|
|
import static com.android.launcher3.LauncherState.NORMAL;
|
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
|
import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS;
|
|
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
|
|
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
|
|
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
|
|
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
|
|
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
|
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
|
|
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
|
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
|
|
import static com.android.launcher3.logging.StatsLogManager.getLauncherAtomEvent;
|
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
|
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
|
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
|
|
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
|
|
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
|
|
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
|
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
|
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
|
|
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
|
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
|
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
|
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
|
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.Animator.AnimatorListener;
|
|
import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.ValueAnimator;
|
|
import android.graphics.PointF;
|
|
import android.util.Log;
|
|
import android.view.MotionEvent;
|
|
import android.view.animation.Interpolator;
|
|
|
|
import com.android.launcher3.BaseQuickstepLauncher;
|
|
import com.android.launcher3.LauncherState;
|
|
import com.android.launcher3.R;
|
|
import com.android.launcher3.Utilities;
|
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
|
import com.android.launcher3.anim.PendingAnimation;
|
|
import com.android.launcher3.states.StateAnimationConfig;
|
|
import com.android.launcher3.touch.BaseSwipeDetector;
|
|
import com.android.launcher3.touch.BothAxesSwipeDetector;
|
|
import com.android.launcher3.util.TouchController;
|
|
import com.android.launcher3.util.VibratorWrapper;
|
|
import com.android.quickstep.AnimatedFloat;
|
|
import com.android.quickstep.SystemUiProxy;
|
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
|
import com.android.quickstep.util.LayoutUtils;
|
|
import com.android.quickstep.util.MotionPauseDetector;
|
|
import com.android.quickstep.util.WorkspaceRevealAnim;
|
|
import com.android.quickstep.views.LauncherRecentsView;
|
|
|
|
/**
|
|
* Handles quick switching to a recent task from the home screen. To give as much flexibility to
|
|
* the user as possible, also handles swipe up and hold to go to overview and swiping back home.
|
|
*/
|
|
public class NoButtonQuickSwitchTouchController implements TouchController,
|
|
BothAxesSwipeDetector.Listener {
|
|
|
|
private static final float Y_ANIM_MIN_PROGRESS = 0.25f;
|
|
private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_3;
|
|
private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCEL_0_75;
|
|
private static final Interpolator SCALE_DOWN_INTERPOLATOR = LINEAR;
|
|
private static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
|
|
|
|
private final BaseQuickstepLauncher mLauncher;
|
|
private final BothAxesSwipeDetector mSwipeDetector;
|
|
private final float mXRange;
|
|
private final float mYRange;
|
|
private final float mMaxYProgress;
|
|
private final MotionPauseDetector mMotionPauseDetector;
|
|
private final float mMotionPauseMinDisplacement;
|
|
private final LauncherRecentsView mRecentsView;
|
|
protected final AnimatorListener mClearStateOnCancelListener =
|
|
newCancelListener(this::clearState);
|
|
|
|
private boolean mNoIntercept;
|
|
private LauncherState mStartState;
|
|
|
|
private boolean mIsHomeScreenVisible = true;
|
|
|
|
// As we drag, we control 3 animations: one to get non-overview components out of the way,
|
|
// and the other two to set overview properties based on x and y progress.
|
|
private AnimatorPlaybackController mNonOverviewAnim;
|
|
private AnimatorPlaybackController mXOverviewAnim;
|
|
private AnimatedFloat mYOverviewAnim;
|
|
|
|
public NoButtonQuickSwitchTouchController(BaseQuickstepLauncher launcher) {
|
|
mLauncher = launcher;
|
|
mSwipeDetector = new BothAxesSwipeDetector(mLauncher, this);
|
|
mRecentsView = mLauncher.getOverviewPanel();
|
|
mXRange = mLauncher.getDeviceProfile().widthPx / 2f;
|
|
mYRange = LayoutUtils.getShelfTrackingDistance(
|
|
mLauncher, mLauncher.getDeviceProfile(), mRecentsView.getPagedOrientationHandler());
|
|
mMaxYProgress = mLauncher.getDeviceProfile().heightPx / mYRange;
|
|
mMotionPauseDetector = new MotionPauseDetector(mLauncher);
|
|
mMotionPauseMinDisplacement = mLauncher.getResources().getDimension(
|
|
R.dimen.motion_pause_detector_min_displacement_from_app);
|
|
}
|
|
|
|
@Override
|
|
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
|
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
|
mNoIntercept = !canInterceptTouch(ev);
|
|
if (mNoIntercept) {
|
|
return false;
|
|
}
|
|
|
|
// Only detect horizontal swipe for intercept, then we will allow swipe up as well.
|
|
mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT,
|
|
false /* ignoreSlopWhenSettling */);
|
|
}
|
|
|
|
if (mNoIntercept) {
|
|
return false;
|
|
}
|
|
|
|
onControllerTouchEvent(ev);
|
|
return mSwipeDetector.isDraggingOrSettling();
|
|
}
|
|
|
|
@Override
|
|
public boolean onControllerTouchEvent(MotionEvent ev) {
|
|
return mSwipeDetector.onTouchEvent(ev);
|
|
}
|
|
|
|
private boolean canInterceptTouch(MotionEvent ev) {
|
|
if (!mLauncher.isInState(LauncherState.NORMAL)) {
|
|
return false;
|
|
}
|
|
if ((ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) == 0) {
|
|
return false;
|
|
}
|
|
int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
|
|
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onDragStart(boolean start) {
|
|
mMotionPauseDetector.clear();
|
|
if (start) {
|
|
mStartState = mLauncher.getStateManager().getState();
|
|
|
|
mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);
|
|
|
|
// We have detected horizontal drag start, now allow swipe up as well.
|
|
mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT | DIRECTION_UP,
|
|
false /* ignoreSlopWhenSettling */);
|
|
|
|
setupAnimators();
|
|
}
|
|
}
|
|
|
|
private void onMotionPauseDetected() {
|
|
VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
|
|
}
|
|
|
|
private void setupAnimators() {
|
|
// Animate the non-overview components (e.g. workspace, shelf) out of the way.
|
|
StateAnimationConfig nonOverviewBuilder = new StateAnimationConfig();
|
|
nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_FADE, FADE_OUT_INTERPOLATOR);
|
|
nonOverviewBuilder.setInterpolator(ANIM_ALL_APPS_FADE, FADE_OUT_INTERPOLATOR);
|
|
nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_SCALE, FADE_OUT_INTERPOLATOR);
|
|
nonOverviewBuilder.setInterpolator(ANIM_DEPTH, FADE_OUT_INTERPOLATOR);
|
|
nonOverviewBuilder.setInterpolator(ANIM_VERTICAL_PROGRESS, TRANSLATE_OUT_INTERPOLATOR);
|
|
updateNonOverviewAnim(QUICK_SWITCH, nonOverviewBuilder);
|
|
mNonOverviewAnim.dispatchOnStart();
|
|
|
|
if (mRecentsView.getTaskViewCount() == 0) {
|
|
mRecentsView.setOnEmptyMessageUpdatedListener(isEmpty -> {
|
|
if (!isEmpty && mSwipeDetector.isDraggingState()) {
|
|
// We have loaded tasks, update the animators to start at the correct scale etc.
|
|
setupOverviewAnimators();
|
|
}
|
|
});
|
|
}
|
|
|
|
setupOverviewAnimators();
|
|
}
|
|
|
|
/** Create state animation to control non-overview components. */
|
|
private void updateNonOverviewAnim(LauncherState toState, StateAnimationConfig config) {
|
|
config.duration = (long) (Math.max(mXRange, mYRange) * 2);
|
|
config.animFlags |= SKIP_OVERVIEW | SKIP_SCRIM;
|
|
mNonOverviewAnim = mLauncher.getStateManager()
|
|
.createAnimationToNewWorkspace(toState, config);
|
|
mNonOverviewAnim.getTarget().addListener(mClearStateOnCancelListener);
|
|
}
|
|
|
|
private void setupOverviewAnimators() {
|
|
final LauncherState fromState = QUICK_SWITCH;
|
|
final LauncherState toState = OVERVIEW;
|
|
|
|
// Set RecentView's initial properties.
|
|
RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
|
|
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f);
|
|
mRecentsView.setContentAlpha(1);
|
|
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
|
|
mLauncher.getActionsView().getVisibilityAlpha().setValue(
|
|
(fromState.getVisibleElements(mLauncher) & OVERVIEW_ACTIONS) != 0 ? 1f : 0f);
|
|
Log.v("b/193125090", "NoButtonQuickSwitchTouchController - setVisibilityAlpha: "
|
|
+ mLauncher.getActionsView().getVisibilityAlpha().getValue());
|
|
|
|
float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher);
|
|
// As we drag right, animate the following properties:
|
|
// - RecentsView translationX
|
|
// - OverviewScrim
|
|
// - RecentsView fade (if it's empty)
|
|
PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
|
|
xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR);
|
|
xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
|
|
toState.getWorkspaceScrimColor(mLauncher), LINEAR);
|
|
if (mRecentsView.getTaskViewCount() == 0) {
|
|
xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
|
|
}
|
|
mXOverviewAnim = xAnim.createPlaybackController();
|
|
mXOverviewAnim.dispatchOnStart();
|
|
|
|
// As we drag up, animate the following properties:
|
|
// - RecentsView scale
|
|
// - RecentsView fullscreenProgress
|
|
PendingAnimation yAnim = new PendingAnimation((long) (mYRange * 2));
|
|
yAnim.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
|
|
SCALE_DOWN_INTERPOLATOR);
|
|
yAnim.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
|
|
toState.getOverviewFullscreenProgress(), SCALE_DOWN_INTERPOLATOR);
|
|
AnimatorPlaybackController yNormalController = yAnim.createPlaybackController();
|
|
AnimatorControllerWithResistance yAnimWithResistance = AnimatorControllerWithResistance
|
|
.createForRecents(yNormalController, mLauncher,
|
|
mRecentsView.getPagedViewOrientedState(), mLauncher.getDeviceProfile(),
|
|
mRecentsView, RECENTS_SCALE_PROPERTY, mRecentsView,
|
|
TASK_SECONDARY_TRANSLATION);
|
|
mYOverviewAnim = new AnimatedFloat(() -> {
|
|
if (mYOverviewAnim != null) {
|
|
yAnimWithResistance.setProgress(mYOverviewAnim.value, mMaxYProgress);
|
|
}
|
|
});
|
|
yNormalController.dispatchOnStart();
|
|
}
|
|
|
|
@Override
|
|
public boolean onDrag(PointF displacement, MotionEvent ev) {
|
|
float xProgress = Math.max(0, displacement.x) / mXRange;
|
|
float yProgress = Math.max(0, -displacement.y) / mYRange;
|
|
yProgress = Utilities.mapRange(yProgress, Y_ANIM_MIN_PROGRESS, 1f);
|
|
|
|
boolean wasHomeScreenVisible = mIsHomeScreenVisible;
|
|
if (wasHomeScreenVisible && mNonOverviewAnim != null) {
|
|
mNonOverviewAnim.setPlayFraction(xProgress);
|
|
}
|
|
mIsHomeScreenVisible = FADE_OUT_INTERPOLATOR.getInterpolation(xProgress)
|
|
<= 1 - ALPHA_CUTOFF_THRESHOLD;
|
|
|
|
mMotionPauseDetector.setDisallowPause(-displacement.y < mMotionPauseMinDisplacement);
|
|
mMotionPauseDetector.addPosition(ev);
|
|
|
|
if (mXOverviewAnim != null) {
|
|
mXOverviewAnim.setPlayFraction(xProgress);
|
|
}
|
|
if (mYOverviewAnim != null) {
|
|
mYOverviewAnim.updateValue(yProgress);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onDragEnd(PointF velocity) {
|
|
boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
|
|
boolean verticalFling = mSwipeDetector.isFling(velocity.y);
|
|
boolean noFling = !horizontalFling && !verticalFling;
|
|
if (mMotionPauseDetector.isPaused() && noFling) {
|
|
cancelAnimations();
|
|
|
|
StateAnimationConfig config = new StateAnimationConfig();
|
|
config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
|
Animator overviewAnim = mLauncher.getStateManager().createAtomicAnimation(
|
|
mStartState, OVERVIEW, config);
|
|
overviewAnim.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
onAnimationToStateCompleted(OVERVIEW);
|
|
}
|
|
});
|
|
overviewAnim.start();
|
|
return;
|
|
}
|
|
|
|
final LauncherState targetState;
|
|
if (horizontalFling && verticalFling) {
|
|
if (velocity.x < 0) {
|
|
// Flinging left and up or down both go back home.
|
|
targetState = NORMAL;
|
|
} else {
|
|
if (velocity.y > 0) {
|
|
// Flinging right and down goes to quick switch.
|
|
targetState = QUICK_SWITCH;
|
|
} else {
|
|
// Flinging up and right could go either home or to quick switch.
|
|
// Determine the target based on the higher velocity.
|
|
targetState = Math.abs(velocity.x) > Math.abs(velocity.y)
|
|
? QUICK_SWITCH : NORMAL;
|
|
}
|
|
}
|
|
} else if (horizontalFling) {
|
|
targetState = velocity.x > 0 ? QUICK_SWITCH : NORMAL;
|
|
} else if (verticalFling) {
|
|
targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
|
|
} else {
|
|
// If user isn't flinging, just snap to the closest state.
|
|
boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
|
|
boolean passedVerticalThreshold = mYOverviewAnim.value > 1f;
|
|
targetState = passedHorizontalThreshold && !passedVerticalThreshold
|
|
? QUICK_SWITCH : NORMAL;
|
|
}
|
|
|
|
// Animate the various components to the target state.
|
|
|
|
float xProgress = mXOverviewAnim.getProgressFraction();
|
|
float startXProgress = Utilities.boundToRange(xProgress
|
|
+ velocity.x * getSingleFrameMs(mLauncher) / mXRange, 0f, 1f);
|
|
final float endXProgress = targetState == NORMAL ? 0 : 1;
|
|
long xDuration = BaseSwipeDetector.calculateDuration(velocity.x,
|
|
Math.abs(endXProgress - startXProgress));
|
|
ValueAnimator xOverviewAnim = mXOverviewAnim.getAnimationPlayer();
|
|
xOverviewAnim.setFloatValues(startXProgress, endXProgress);
|
|
xOverviewAnim.setDuration(xDuration)
|
|
.setInterpolator(scrollInterpolatorForVelocity(velocity.x));
|
|
mXOverviewAnim.dispatchOnStart();
|
|
|
|
boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
|
|
|
|
float yProgress = mYOverviewAnim.value;
|
|
float startYProgress = Utilities.boundToRange(yProgress
|
|
- velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, mMaxYProgress);
|
|
final float endYProgress;
|
|
if (flingUpToNormal) {
|
|
endYProgress = 1;
|
|
} else if (targetState == NORMAL) {
|
|
// Keep overview at its current scale/translationY as it slides off the screen.
|
|
endYProgress = startYProgress;
|
|
} else {
|
|
endYProgress = 0;
|
|
}
|
|
float yDistanceToCover = Math.abs(endYProgress - startYProgress) * mYRange;
|
|
long yDuration = (long) (yDistanceToCover / Math.max(1f, Math.abs(velocity.y)));
|
|
ValueAnimator yOverviewAnim = mYOverviewAnim.animateToValue(startYProgress, endYProgress);
|
|
yOverviewAnim.setDuration(yDuration);
|
|
mYOverviewAnim.updateValue(startYProgress);
|
|
|
|
ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
|
|
if (flingUpToNormal && !mIsHomeScreenVisible) {
|
|
// We are flinging to home while workspace is invisible, run the same staggered
|
|
// animation as from an app.
|
|
StateAnimationConfig config = new StateAnimationConfig();
|
|
// Update mNonOverviewAnim to do nothing so it doesn't interfere.
|
|
config.animFlags = SKIP_ALL_ANIMATIONS;
|
|
updateNonOverviewAnim(targetState, config);
|
|
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
|
|
|
|
new WorkspaceRevealAnim(mLauncher, false /* animateOverviewScrim */).start();
|
|
} else {
|
|
boolean canceled = targetState == NORMAL;
|
|
if (canceled) {
|
|
// Let the state manager know that the animation didn't go to the target state,
|
|
// but don't clean up yet (we already clean up when the animation completes).
|
|
mNonOverviewAnim.getTarget().removeListener(mClearStateOnCancelListener);
|
|
mNonOverviewAnim.dispatchOnCancel();
|
|
}
|
|
float startProgress = mNonOverviewAnim.getProgressFraction();
|
|
float endProgress = canceled ? 0 : 1;
|
|
nonOverviewAnim.setFloatValues(startProgress, endProgress);
|
|
mNonOverviewAnim.dispatchOnStart();
|
|
}
|
|
|
|
nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
|
|
mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState));
|
|
|
|
cancelAnimations();
|
|
xOverviewAnim.start();
|
|
yOverviewAnim.start();
|
|
nonOverviewAnim.start();
|
|
}
|
|
|
|
private void onAnimationToStateCompleted(LauncherState targetState) {
|
|
mLauncher.getStatsLogManager().logger()
|
|
.withSrcState(LAUNCHER_STATE_HOME)
|
|
.withDstState(targetState.statsLogOrdinal)
|
|
.log(getLauncherAtomEvent(mStartState.statsLogOrdinal, targetState.statsLogOrdinal,
|
|
targetState.ordinal > mStartState.ordinal
|
|
? LAUNCHER_UNKNOWN_SWIPEUP
|
|
: LAUNCHER_UNKNOWN_SWIPEDOWN));
|
|
mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState));
|
|
}
|
|
|
|
private void cancelAnimations() {
|
|
if (mNonOverviewAnim != null) {
|
|
mNonOverviewAnim.getAnimationPlayer().cancel();
|
|
}
|
|
if (mXOverviewAnim != null) {
|
|
mXOverviewAnim.getAnimationPlayer().cancel();
|
|
}
|
|
if (mYOverviewAnim != null) {
|
|
mYOverviewAnim.cancelAnimation();
|
|
}
|
|
mMotionPauseDetector.clear();
|
|
}
|
|
|
|
private void clearState() {
|
|
cancelAnimations();
|
|
mNonOverviewAnim = null;
|
|
mXOverviewAnim = null;
|
|
mYOverviewAnim = null;
|
|
mIsHomeScreenVisible = true;
|
|
mSwipeDetector.finishedScrolling();
|
|
mRecentsView.setOnEmptyMessageUpdatedListener(null);
|
|
}
|
|
}
|