Merge "Add long swipe from app to overview gesture (with flag)." into udc-dev am: a4627d2235
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/22243545 Change-Id: I73c6d04586d2e8d44ecab3706939c53e2a258b71 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -39,6 +39,7 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.ALL_APPS;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
|
||||
@@ -161,6 +162,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
|
||||
|
||||
/** Shift distance to transition to All Apps if ENABLE_ALL_APPS_FROM_OVERVIEW. */
|
||||
public static final float ALL_APPS_SHIFT_THRESHOLD = 2f;
|
||||
|
||||
protected final BaseActivityInterface<S, T> mActivityInterface;
|
||||
protected final InputConsumerProxy mInputConsumerProxy;
|
||||
protected final ActivityInitListener mActivityInitListener;
|
||||
@@ -247,6 +251,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
getNextStateFlag("STATE_CURRENT_TASK_FINISHED");
|
||||
private static final int STATE_FINISH_WITH_NO_END =
|
||||
getNextStateFlag("STATE_FINISH_WITH_NO_END");
|
||||
private static final int STATE_SETTLED_ON_ALL_APPS =
|
||||
getNextStateFlag("STATE_SETTLED_ON_ALL_APPS");
|
||||
|
||||
private static final int LAUNCHER_UI_STATES =
|
||||
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED |
|
||||
@@ -299,6 +305,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
private boolean mGestureStarted;
|
||||
private boolean mLogDirectionUpOrLeft = true;
|
||||
private boolean mIsLikelyToStartNewTask;
|
||||
private boolean mIsInAllAppsRegion;
|
||||
|
||||
private final long mTouchTimeMs;
|
||||
private long mLauncherFrameDrawnTime;
|
||||
@@ -432,6 +439,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
this::finishCurrentTransitionToHome);
|
||||
mStateCallback.runOnceAtState(STATE_SCALED_CONTROLLER_HOME | STATE_CURRENT_TASK_FINISHED,
|
||||
this::reset);
|
||||
mStateCallback.runOnceAtState(STATE_SETTLED_ON_ALL_APPS | STATE_SCREENSHOT_CAPTURED
|
||||
| STATE_GESTURE_COMPLETED,
|
||||
this::finishCurrentTransitionToAllApps);
|
||||
|
||||
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
|
||||
| STATE_LAUNCHER_DRAWN | STATE_SCALED_CONTROLLER_RECENTS
|
||||
@@ -681,7 +691,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
|
||||
Optional.ofNullable(mActivityInterface.getTaskbarController())
|
||||
.ifPresent(TaskbarUIController::startTranslationSpring);
|
||||
performHapticFeedback();
|
||||
if (!mIsInAllAppsRegion) {
|
||||
performHapticFeedback();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -695,7 +707,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
maybeUpdateRecentsAttachedState(true /* animate */);
|
||||
}
|
||||
|
||||
private void maybeUpdateRecentsAttachedState(boolean animate) {
|
||||
protected void maybeUpdateRecentsAttachedState(boolean animate) {
|
||||
maybeUpdateRecentsAttachedState(animate, false /* moveRunningTask */);
|
||||
}
|
||||
|
||||
@@ -716,7 +728,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId())
|
||||
: null;
|
||||
final boolean recentsAttachedToAppWindow;
|
||||
if (mGestureState.getEndTarget() != null) {
|
||||
if (mIsInAllAppsRegion) {
|
||||
recentsAttachedToAppWindow = false;
|
||||
} else if (mGestureState.getEndTarget() != null) {
|
||||
recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
|
||||
} else if (mContinuingLastGesture
|
||||
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
|
||||
@@ -772,6 +786,26 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update whether user is currently dragging in a region that will trigger all apps.
|
||||
*/
|
||||
private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
|
||||
if (mIsInAllAppsRegion == isInAllAppsRegion
|
||||
|| !mActivityInterface.allowAllAppsFromOverview()) {
|
||||
return;
|
||||
}
|
||||
mIsInAllAppsRegion = isInAllAppsRegion;
|
||||
|
||||
// Newly entering or exiting the zone - do haptic and animate recent tasks.
|
||||
VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
|
||||
maybeUpdateRecentsAttachedState(true);
|
||||
|
||||
// Draw active task below Launcher so that All Apps can appear over it.
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(isInAllAppsRegion));
|
||||
}
|
||||
|
||||
|
||||
private void buildAnimationController() {
|
||||
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||
return;
|
||||
@@ -792,10 +826,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
|
||||
WindowInsets result = view.onApplyWindowInsets(windowInsets);
|
||||
// Don't rebuild animation when we are animating the IME, because it will cause a loop
|
||||
// where the insets change -> animation changes (updating ime) -> insets change -> ...
|
||||
if (windowInsets.isVisible(WindowInsets.Type.ime())) {
|
||||
return result;
|
||||
}
|
||||
buildAnimationController();
|
||||
// Reapply the current shift to ensure it takes new insets into account, e.g. when long
|
||||
// pressing to stash taskbar without moving the finger.
|
||||
updateFinalShift();
|
||||
onCurrentShiftUpdated();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -822,7 +861,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
*/
|
||||
@UiThread
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
public void onCurrentShiftUpdated() {
|
||||
setIsInAllAppsRegion(mCurrentShift.value >= ALL_APPS_SHIFT_THRESHOLD);
|
||||
updateSysUiFlags(mCurrentShift.value);
|
||||
applyScrollAndTransform();
|
||||
|
||||
@@ -1085,6 +1125,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
|
||||
switch (endTarget) {
|
||||
case ALL_APPS:
|
||||
mStateCallback.setState(STATE_SETTLED_ON_ALL_APPS | STATE_CAPTURE_SCREENSHOT);
|
||||
break;
|
||||
case HOME:
|
||||
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
|
||||
// Notify the SysUI to use fade-in animation when entering PiP
|
||||
@@ -1173,6 +1216,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
final boolean willGoToNewTask =
|
||||
isScrollingToNewTask() && Math.abs(velocity.x) > Math.abs(endVelocity);
|
||||
final boolean isSwipeUp = endVelocity < 0;
|
||||
if (mIsInAllAppsRegion) {
|
||||
return isSwipeUp ? ALL_APPS : LAST_TASK;
|
||||
}
|
||||
if (!isSwipeUp) {
|
||||
final boolean isCenteredOnNewTask =
|
||||
mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
|
||||
@@ -1188,7 +1234,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// Fully gestural mode.
|
||||
final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
|
||||
.getDimension(R.dimen.quickstep_fling_threshold_speed);
|
||||
if (isScrollingToNewTask && isFlingX) {
|
||||
if (mIsInAllAppsRegion) {
|
||||
return ALL_APPS;
|
||||
} else if (isScrollingToNewTask && isFlingX) {
|
||||
// Flinging towards new task takes precedence over mIsMotionPaused (which only
|
||||
// checks y-velocity).
|
||||
return NEW_TASK;
|
||||
@@ -1236,7 +1284,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mGestureState.setEndTarget(endTarget, false /* isAtomic */);
|
||||
mAnimationFactory.setEndTarget(endTarget);
|
||||
|
||||
float endShift = endTarget.isLauncher ? 1 : 0;
|
||||
float endShift = endTarget == ALL_APPS ? mDragLengthFactor
|
||||
: endTarget.isLauncher ? 1 : 0;
|
||||
final float startShift;
|
||||
if (!isFling) {
|
||||
long expectedDuration = Math.abs(Math.round((endShift - currentShift)
|
||||
@@ -1793,6 +1842,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
reset();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void finishCurrentTransitionToAllApps() {
|
||||
finishCurrentTransitionToHome();
|
||||
reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
if (mActivity != null) {
|
||||
@@ -1926,7 +1981,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
private boolean updateThumbnail(int runningTaskId, boolean refreshView) {
|
||||
boolean finishTransitionPosted = false;
|
||||
final TaskView taskView;
|
||||
if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK) {
|
||||
if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK
|
||||
|| mGestureState.getEndTarget() == ALL_APPS) {
|
||||
// Capture the screenshot before finishing the transition to home or quickswitching to
|
||||
// ensure it's taken in the correct orientation, but no need to update the thumbnail.
|
||||
taskView = null;
|
||||
@@ -2072,7 +2128,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private void onRecentsViewScroll() {
|
||||
if (moveWindowWithRecentsScroll()) {
|
||||
updateFinalShift();
|
||||
onCurrentShiftUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|
||||
public abstract boolean allowMinimizeSplitScreen();
|
||||
|
||||
/** @return whether to allow going to All Apps from Overview. */
|
||||
public abstract boolean allowAllAppsFromOverview();
|
||||
|
||||
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
|
||||
return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons()
|
||||
|| isTrackpadMultiFingerSwipe(ev);
|
||||
|
||||
@@ -138,6 +138,11 @@ public final class FallbackActivityInterface extends
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowAllAppsFromOverview() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
|
||||
// In non-gesture mode, user might be clicking on the home button which would directly
|
||||
@@ -196,6 +201,7 @@ public final class FallbackActivityInterface extends
|
||||
case LAST_TASK:
|
||||
return BACKGROUND_APP;
|
||||
case HOME:
|
||||
case ALL_APPS:
|
||||
default:
|
||||
return HOME;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ package com.android.quickstep;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadThreeFingerSwipe;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_ALL_APPS;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_HOME;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
|
||||
|
||||
@@ -68,7 +70,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
GestureStateProto.GestureEndTarget.NEW_TASK),
|
||||
|
||||
LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true,
|
||||
GestureStateProto.GestureEndTarget.LAST_TASK);
|
||||
GestureStateProto.GestureEndTarget.LAST_TASK),
|
||||
|
||||
ALL_APPS(true, LAUNCHER_STATE_ALLAPPS, false, GestureStateProto.GestureEndTarget.ALL_APPS);
|
||||
|
||||
GestureEndTarget(boolean isLauncher, int containerType, boolean recentsAttachedToAppWindow,
|
||||
GestureStateProto.GestureEndTarget protoEndTarget) {
|
||||
@@ -385,6 +389,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
case NEW_TASK:
|
||||
ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_NEW_TASK);
|
||||
break;
|
||||
case ALL_APPS:
|
||||
ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_ALL_APPS);
|
||||
break;
|
||||
case LAST_TASK:
|
||||
case RECENTS:
|
||||
default:
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
@@ -39,6 +40,7 @@ import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.LauncherInitListener;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
@@ -263,6 +265,11 @@ public final class LauncherActivityInterface extends
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowAllAppsFromOverview() {
|
||||
return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLiveTileMode() {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
@@ -347,6 +354,8 @@ public final class LauncherActivityInterface extends
|
||||
case NEW_TASK:
|
||||
case LAST_TASK:
|
||||
return BACKGROUND_APP;
|
||||
case ALL_APPS:
|
||||
return ALL_APPS;
|
||||
case HOME:
|
||||
default:
|
||||
return NORMAL;
|
||||
|
||||
@@ -350,7 +350,8 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
|
||||
enableMultipleRegions(true);
|
||||
}
|
||||
activityInterface.onExitOverview(this, mExitOverviewRunnable);
|
||||
} else if (endTarget == GestureState.GestureEndTarget.HOME) {
|
||||
} else if (endTarget == GestureState.GestureEndTarget.HOME
|
||||
|| endTarget == GestureState.GestureEndTarget.ALL_APPS) {
|
||||
enableMultipleRegions(false);
|
||||
} else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
|
||||
if (mOrientationTouchTransformer.getQuickStepStartingRotation() == -1) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
|
||||
// 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
|
||||
// visible.
|
||||
protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
|
||||
protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::onCurrentShiftUpdated);
|
||||
protected float mCurrentDisplacement;
|
||||
|
||||
// The distance needed to drag to reach the task size in recents.
|
||||
@@ -148,7 +148,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
* Called when the value of {@link #mCurrentShift} changes
|
||||
*/
|
||||
@UiThread
|
||||
public abstract void updateFinalShift();
|
||||
public abstract void onCurrentShiftUpdated();
|
||||
|
||||
protected PagedOrientationHandler getOrientationHandler() {
|
||||
// OrientationHandler should be independent of remote target, can directly take one
|
||||
|
||||
+1
-1
@@ -309,7 +309,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
public void onCurrentShiftUpdated() {
|
||||
mRemoteTargetHandles[0].getPlaybackController()
|
||||
.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().apply(
|
||||
|
||||
@@ -33,10 +33,11 @@ public class ActiveGestureErrorDetector {
|
||||
*/
|
||||
public enum GestureEvent {
|
||||
MOTION_DOWN, MOTION_UP, MOTION_MOVE, SET_END_TARGET, SET_END_TARGET_HOME,
|
||||
SET_END_TARGET_NEW_TASK, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
|
||||
FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
|
||||
CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED,
|
||||
EXPECTING_TASK_APPEARED, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
|
||||
SET_END_TARGET_NEW_TASK, SET_END_TARGET_ALL_APPS, ON_SETTLED_ON_END_TARGET,
|
||||
START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION,
|
||||
SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
|
||||
SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
|
||||
FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
|
||||
|
||||
/**
|
||||
* These GestureEvents are specifically associated to state flags that get set in
|
||||
@@ -220,6 +221,7 @@ public class ActiveGestureErrorDetector {
|
||||
case MOTION_DOWN:
|
||||
case SET_END_TARGET:
|
||||
case SET_END_TARGET_HOME:
|
||||
case SET_END_TARGET_ALL_APPS:
|
||||
case SET_END_TARGET_NEW_TASK:
|
||||
case START_RECENTS_ANIMATION:
|
||||
case SET_ON_PAGE_TRANSITION_END_CALLBACK:
|
||||
|
||||
@@ -17,9 +17,11 @@ package com.android.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.AbsSwipeUpHandler.ALL_APPS_SHIFT_THRESHOLD;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
@@ -32,11 +34,15 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.AllAppsSwipeController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.quickstep.LauncherActivityInterface;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
@@ -49,7 +55,9 @@ public class AnimatorControllerWithResistance {
|
||||
|
||||
private enum RecentsResistanceParams {
|
||||
FROM_APP(0.75f, 0.5f, 1f, false),
|
||||
FROM_APP_TO_ALL_APPS(0.75f, 0.5f, 0.8f, false),
|
||||
FROM_APP_TABLET(1f, 0.7f, 1f, true),
|
||||
FROM_APP_TO_ALL_APPS_TABLET(1f, 0.5f, 0.5f, false),
|
||||
FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
|
||||
|
||||
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
|
||||
@@ -86,6 +94,8 @@ public class AnimatorControllerWithResistance {
|
||||
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
|
||||
private static final TimeInterpolator RECENTS_TRANSLATE_RESIST_INTERPOLATOR = LINEAR;
|
||||
|
||||
private static final Rect TEMP_RECT = new Rect();
|
||||
|
||||
private final AnimatorPlaybackController mNormalController;
|
||||
private final AnimatorPlaybackController mResistanceController;
|
||||
|
||||
@@ -145,10 +155,42 @@ public class AnimatorControllerWithResistance {
|
||||
scaleProperty, translationTarget, translationProperty);
|
||||
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
|
||||
|
||||
// Apply All Apps animation during the resistance animation.
|
||||
if (recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()) {
|
||||
StatefulActivity activity =
|
||||
recentsOrientedState.getActivityInterface().getCreatedActivity();
|
||||
if (activity != null) {
|
||||
StateManager<LauncherState> stateManager = activity.getStateManager();
|
||||
if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
|
||||
&& stateManager.isInTransition()) {
|
||||
|
||||
// Calculate the resistance progress threshold where All Apps will trigger.
|
||||
float threshold = getAllAppsThreshold(context, recentsOrientedState, dp);
|
||||
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
AllAppsSwipeController.applyOverviewToAllAppsAnimConfig(dp, config, threshold);
|
||||
AnimatorSet allAppsAnimator = stateManager.createAnimationToNewWorkspace(
|
||||
LauncherState.ALL_APPS, config).getTarget();
|
||||
resistAnim.add(allAppsAnimator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
|
||||
return new AnimatorControllerWithResistance(normalController, resistanceController);
|
||||
}
|
||||
|
||||
private static float getAllAppsThreshold(Context context,
|
||||
RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
|
||||
int transitionDragLength =
|
||||
recentsOrientedState.getActivityInterface().getSwipeUpDestinationAndLength(
|
||||
dp, context, TEMP_RECT,
|
||||
recentsOrientedState.getOrientationHandler());
|
||||
float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
|
||||
// -1s are because 0-1 is reserved for the normal transition.
|
||||
return (ALL_APPS_SHIFT_THRESHOLD - 1) / (dragLengthFactor - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the resistance animation for {@link #createForRecents}, or can be used separately
|
||||
* when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
|
||||
@@ -158,8 +200,8 @@ public class AnimatorControllerWithResistance {
|
||||
Rect startRect = new Rect();
|
||||
PagedOrientationHandler orientationHandler = params.recentsOrientedState
|
||||
.getOrientationHandler();
|
||||
LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
|
||||
orientationHandler);
|
||||
params.recentsOrientedState.getActivityInterface()
|
||||
.calculateTaskSize(params.context, params.dp, startRect, orientationHandler);
|
||||
long distanceToCover = startRect.bottom;
|
||||
PendingAnimation resistAnim = params.resistAnim != null
|
||||
? params.resistAnim
|
||||
@@ -257,9 +299,15 @@ public class AnimatorControllerWithResistance {
|
||||
this.translationTarget = translationTarget;
|
||||
this.translationProperty = translationProperty;
|
||||
if (dp.isTablet) {
|
||||
resistanceParams = RecentsResistanceParams.FROM_APP_TABLET;
|
||||
resistanceParams =
|
||||
recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
|
||||
: RecentsResistanceParams.FROM_APP_TABLET;
|
||||
} else {
|
||||
resistanceParams = RecentsResistanceParams.FROM_APP;
|
||||
resistanceParams =
|
||||
recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
|
||||
: RecentsResistanceParams.FROM_APP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ public class RecentsOrientedState implements
|
||||
| FLAG_SWIPE_UP_NOT_RUNNING;
|
||||
|
||||
private final Context mContext;
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final OrientationEventListener mOrientationListener;
|
||||
private final SettingsCache mSettingsCache;
|
||||
private final SettingsCache.OnChangeListener mRotationChangeListener =
|
||||
@@ -135,9 +136,10 @@ public class RecentsOrientedState implements
|
||||
* is enabled
|
||||
* @see #setRotationWatcherEnabled(boolean)
|
||||
*/
|
||||
public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy,
|
||||
public RecentsOrientedState(Context context, BaseActivityInterface activityInterface,
|
||||
IntConsumer rotationChangeListener) {
|
||||
mContext = context;
|
||||
mActivityInterface = activityInterface;
|
||||
mOrientationListener = new OrientationEventListener(context) {
|
||||
@Override
|
||||
public void onOrientationChanged(int degrees) {
|
||||
@@ -149,7 +151,7 @@ public class RecentsOrientedState implements
|
||||
}
|
||||
};
|
||||
|
||||
mFlags = sizeStrategy.rotationSupportedByActivity
|
||||
mFlags = mActivityInterface.rotationSupportedByActivity
|
||||
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
|
||||
|
||||
mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
|
||||
@@ -157,6 +159,10 @@ public class RecentsOrientedState implements
|
||||
initFlags();
|
||||
}
|
||||
|
||||
public BaseActivityInterface getActivityInterface() {
|
||||
return mActivityInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the device profile for the current state.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.quickstep.views;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
@@ -129,7 +130,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
if (finalState == NORMAL || finalState == SPRING_LOADED) {
|
||||
if (finalState == NORMAL || finalState == SPRING_LOADED || finalState == ALL_APPS) {
|
||||
// Clean-up logic that occurs when recents is no longer in use/visible.
|
||||
reset();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user