diff --git a/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java b/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java index 1977e93a79..6df1aba01d 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java +++ b/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java @@ -29,8 +29,8 @@ public class DragPauseDetector implements OnAlarmListener { private final Alarm mAlarm; private final Runnable mOnPauseCallback; - private boolean mEnabled = true; private boolean mTriggered = false; + private int mDisabledFlags = 0; public DragPauseDetector(Runnable onPauseCallback) { mOnPauseCallback = onPauseCallback; @@ -40,8 +40,8 @@ public class DragPauseDetector implements OnAlarmListener { mAlarm.setAlarm(PAUSE_DURATION); } - public void onDrag(float displacement, float velocity) { - if (mTriggered || !mEnabled) { + public void onDrag(float velocity) { + if (mTriggered || !isEnabled()) { return; } @@ -53,7 +53,7 @@ public class DragPauseDetector implements OnAlarmListener { @Override public void onAlarm(Alarm alarm) { - if (!mTriggered && mEnabled) { + if (!mTriggered && isEnabled()) { mTriggered = true; mOnPauseCallback.run(); } @@ -64,17 +64,29 @@ public class DragPauseDetector implements OnAlarmListener { } public boolean isEnabled() { - return mEnabled; + return mDisabledFlags == 0; } - public void setEnabled(boolean isEnabled) { - if (mEnabled != isEnabled) { - mEnabled = isEnabled; - if (isEnabled && !mTriggered) { - mAlarm.setAlarm(PAUSE_DURATION); - } else if (!isEnabled) { - mAlarm.cancelAlarm(); - } + public void addDisabledFlags(int flags) { + boolean wasEnabled = isEnabled(); + mDisabledFlags |= flags; + resetAlarm(wasEnabled); + } + + public void clearDisabledFlags(int flags) { + boolean wasEnabled = isEnabled(); + mDisabledFlags &= ~flags; + resetAlarm(wasEnabled); + } + + private void resetAlarm(boolean wasEnabled) { + boolean isEnabled = isEnabled(); + if (wasEnabled == isEnabled) { + // Nothing has changed + } if (isEnabled && !mTriggered) { + mAlarm.setAlarm(PAUSE_DURATION); + } else if (!isEnabled) { + mAlarm.cancelAlarm(); } } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java index 299db4768f..20cda1cecd 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java @@ -48,6 +48,7 @@ import com.android.launcher3.touch.SwipeDetector; 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.FloatRange; import com.android.launcher3.util.TouchController; import java.util.ArrayList; @@ -78,6 +79,14 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter */ private static final int OTHER_HANDLERS_START_INDEX = SWIPE_HANDLER_INDEX + 1; + // Swipe progress range (when starting from NORMAL state) where OVERVIEW state is allowed + private static final float MIN_PROGRESS_TO_OVERVIEW = 0.1f; + private static final float MAX_PROGRESS_TO_OVERVIEW = 0.4f; + + private static final int FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE = 1 << 0; + private static final int FLAG_OVERVIEW_DISABLED_FLING = 1 << 1; + private static final int FLAG_OVERVIEW_DISABLED_CANCEL_STATE = 1 << 2; + private final Launcher mLauncher; private final SwipeDetector mDetector; @@ -85,6 +94,7 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter private int mStartContainerType; private DragPauseDetector mDragPauseDetector; + private FloatRange mOverviewProgressRange; private TaggedAnimatorSetBuilder mTaggedAnimatorSetBuilder; private AnimatorSet mQuickOverviewAnimation; private boolean mAnimatingToOverview; @@ -221,10 +231,17 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter long maxAccuracy = (long) (2 * range); mDragPauseDetector = new DragPauseDetector(this::onDragPauseDetected); - mTaggedAnimatorSetBuilder = new TaggedAnimatorSetBuilder(); + mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE); + mOverviewProgressRange = new FloatRange(); + mOverviewProgressRange.start = mLauncher.isInState(NORMAL) + ? MIN_PROGRESS_TO_OVERVIEW + : 1 - MAX_PROGRESS_TO_OVERVIEW; + mOverviewProgressRange.end = mOverviewProgressRange.start + + MAX_PROGRESS_TO_OVERVIEW - MIN_PROGRESS_TO_OVERVIEW; // Build current animation mToState = mLauncher.isInState(ALL_APPS) ? NORMAL : ALL_APPS; + mTaggedAnimatorSetBuilder = new TaggedAnimatorSetBuilder(); mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace( mToState, mTaggedAnimatorSetBuilder, maxAccuracy); @@ -235,6 +252,9 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter } else { mCurrentAnimation.pause(); mStartProgress = mCurrentAnimation.getProgressFraction(); + + mDragPauseDetector.clearDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING); + updatePauseDetectorRangeFlag(); } for (SpringAnimationHandler h : mSpringHandlers) { @@ -248,13 +268,23 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter @Override public boolean onDrag(float displacement, float velocity) { - mDragPauseDetector.onDrag(displacement, velocity); - float deltaProgress = mProgressMultiplier * displacement; mCurrentAnimation.setPlayFraction(deltaProgress + mStartProgress); + + updatePauseDetectorRangeFlag(); + mDragPauseDetector.onDrag(velocity); + return true; } + private void updatePauseDetectorRangeFlag() { + if (mOverviewProgressRange.contains(mCurrentAnimation.getProgressFraction())) { + mDragPauseDetector.clearDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE); + } else { + mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE); + } + } + @Override public void onDragEnd(float velocity, boolean fling) { if (!fling && mDragPauseDetector.isEnabled() && mDragPauseDetector.isTriggered()) { @@ -262,6 +292,8 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter return; } + mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING); + final long animationDuration; final int logAction; final LauncherState targetState; @@ -306,9 +338,6 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter anim.setDuration(animationDuration); anim.setInterpolator(scrollInterpolatorForVelocity(velocity)); anim.start(); - - // TODO: Re-enable later - mDragPauseDetector.setEnabled(false); } private void onSwipeInteractionCompleted(LauncherState targetState, int logAction) { @@ -413,7 +442,7 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter mCurrentAnimation = null; mTaggedAnimatorSetBuilder = null; if (mDragPauseDetector != null) { - mDragPauseDetector.setEnabled(false); + mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_CANCEL_STATE); } mDragPauseDetector = null; diff --git a/src/com/android/launcher3/util/FloatRange.java b/src/com/android/launcher3/util/FloatRange.java new file mode 100644 index 0000000000..12772f3654 --- /dev/null +++ b/src/com/android/launcher3/util/FloatRange.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 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.util; + +/** + * A mutable class for describing the range of two int values. + */ +public class FloatRange { + + public float start, end; + + public FloatRange() { } + + public FloatRange(float s, float e) { + set(s, e); + } + + public void set(float s, float e) { + start = s; + end = e; + } + + public boolean contains(float value) { + return value >= start && value <= end; + } +}