10/ Migrate shared state to the gesture state

- Instead of a shared state which is written into, gestures update their
  own gesture state and that state is passed to the next gesture.
- The existing shared state encoded the final end target (which is
  currently directly correlated with canGestureBeContinued). If we move
  the end target calculations to the GestureState, the handlers can listen
  for those changes and we can use the previous gesture state to decide
  which consumer to choose.  In addition, we move over the interrupted-
  finish-launch-task id.

Bug: 141886704

Change-Id: Icb6a3815c16b23692dbcde316114bd3cea06634e
Signed-off-by: Winson Chung <winsonc@google.com>
This commit is contained in:
Winson Chung 2019-10-07 16:51:58 -07:00
parent c9bf6d45ac
commit c80b3224aa
14 changed files with 332 additions and 259 deletions

View File

@ -20,13 +20,14 @@ import android.os.Looper;
import com.android.launcher3.Launcher; import com.android.launcher3.Launcher;
import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.GestureState;
import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView; import com.android.quickstep.views.TaskView;
/** /**
* State to indicate we are about to launch a recent task. Note that this state is only used when * State to indicate we are about to launch a recent task. Note that this state is only used when
* quick switching from launcher; quick switching from an app uses WindowTransformSwipeHelper. * quick switching from launcher; quick switching from an app uses WindowTransformSwipeHelper.
* @see com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget#NEW_TASK * @see GestureState.GestureEndTarget#NEW_TASK
*/ */
public class QuickSwitchState extends BackgroundAppState { public class QuickSwitchState extends BackgroundAppState {

View File

@ -96,6 +96,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
protected float mDragLengthFactor = 1; protected float mDragLengthFactor = 1;
protected final Context mContext; protected final Context mContext;
protected final GestureState mGestureState;
protected final OverviewComponentObserver mOverviewComponentObserver; protected final OverviewComponentObserver mOverviewComponentObserver;
protected final BaseActivityInterface<T> mActivityInterface; protected final BaseActivityInterface<T> mActivityInterface;
protected final RecentsModel mRecentsModel; protected final RecentsModel mRecentsModel;
@ -139,6 +140,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
OverviewComponentObserver overviewComponentObserver, OverviewComponentObserver overviewComponentObserver,
RecentsModel recentsModel, InputConsumerController inputConsumer, int runningTaskId) { RecentsModel recentsModel, InputConsumerController inputConsumer, int runningTaskId) {
mContext = context; mContext = context;
mGestureState = gestureState;
mOverviewComponentObserver = overviewComponentObserver; mOverviewComponentObserver = overviewComponentObserver;
mActivityInterface = gestureState.getActivityInterface(); mActivityInterface = gestureState.getActivityInterface();
mRecentsModel = recentsModel; mRecentsModel = recentsModel;
@ -394,7 +396,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
@UiThread @UiThread
public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos); public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos);
public abstract void onConsumerAboutToBeSwitched(SwipeSharedState sharedState); public abstract void onConsumerAboutToBeSwitched();
public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { } public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { }

View File

@ -1,59 +0,0 @@
/*
* 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.quickstep;
import java.io.PrintWriter;
/**
* Utility class used to store state information shared across multiple transitions.
*/
public class SwipeSharedState {
public boolean canGestureBeContinued;
public boolean goingToLauncher;
public boolean recentsAnimationFinishInterrupted;
public int nextRunningTaskId = -1;
private int mLogId;
/**
* Called when a recents animation has finished, but was interrupted before the next task was
* launched. The given {@param runningTaskId} should be used as the running task for the
* continuing input consumer.
*/
public void setRecentsAnimationFinishInterrupted(int runningTaskId) {
recentsAnimationFinishInterrupted = true;
nextRunningTaskId = runningTaskId;
}
public void clearAllState() {
canGestureBeContinued = false;
recentsAnimationFinishInterrupted = false;
nextRunningTaskId = -1;
goingToLauncher = false;
}
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "goingToLauncher=" + goingToLauncher);
pw.println(prefix + "canGestureBeContinued=" + canGestureBeContinued);
pw.println(prefix + "recentsAnimationFinishInterrupted=" + recentsAnimationFinishInterrupted);
pw.println(prefix + "nextRunningTaskId=" + nextRunningTaskId);
pw.println(prefix + "logTraceId=" + mLogId);
}
public void setLogTraceId(int logId) {
this.mLogId = logId;
}
}

View File

@ -235,8 +235,6 @@ public class TouchInteractionService extends Service implements
private static boolean sConnected = false; private static boolean sConnected = false;
private static boolean sIsInitialized = false; private static boolean sIsInitialized = false;
private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState();
private int mLogId;
public static boolean isConnected() { public static boolean isConnected() {
return sConnected; return sConnected;
@ -246,10 +244,6 @@ public class TouchInteractionService extends Service implements
return sIsInitialized; return sIsInitialized;
} }
public static SwipeSharedState getSwipeSharedState() {
return sSwipeSharedState;
}
private final BaseSwipeUpHandler.Factory mWindowTransformFactory = private final BaseSwipeUpHandler.Factory mWindowTransformFactory =
this::createWindowTransformSwipeHandler; this::createWindowTransformSwipeHandler;
private final BaseSwipeUpHandler.Factory mFallbackNoButtonFactory = private final BaseSwipeUpHandler.Factory mFallbackNoButtonFactory =
@ -267,6 +261,7 @@ public class TouchInteractionService extends Service implements
private InputConsumer mConsumer = InputConsumer.NO_OP; private InputConsumer mConsumer = InputConsumer.NO_OP;
private Choreographer mMainChoreographer; private Choreographer mMainChoreographer;
private InputConsumer mResetGestureInputConsumer; private InputConsumer mResetGestureInputConsumer;
private GestureState mGestureState = new GestureState();
private InputMonitorCompat mInputMonitorCompat; private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver; private InputEventReceiver mInputEventReceiver;
@ -360,7 +355,6 @@ public class TouchInteractionService extends Service implements
mOverviewComponentObserver.getActivityInterface().switchRunningTaskViewToScreenshot( mOverviewComponentObserver.getActivityInterface().switchRunningTaskViewToScreenshot(
null, () -> { null, () -> {
mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */);
sSwipeSharedState.clearAllState();
}); });
} else { } else {
mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */);
@ -440,15 +434,13 @@ public class TouchInteractionService extends Service implements
MotionEvent event = (MotionEvent) ev; MotionEvent event = (MotionEvent) ev;
if (event.getAction() == ACTION_DOWN) { if (event.getAction() == ACTION_DOWN) {
GestureState newGestureState = new GestureState( GestureState newGestureState = new GestureState(
mOverviewComponentObserver.getActivityInterface()); mOverviewComponentObserver.getActivityInterface(),
ActiveGestureLog.INSTANCE.generateAndSetLogId());
mLogId = ActiveGestureLog.INSTANCE.generateAndSetLogId();
sSwipeSharedState.setLogTraceId(mLogId);
if (mDeviceState.isInSwipeUpTouchRegion(event)) { if (mDeviceState.isInSwipeUpTouchRegion(event)) {
boolean useSharedState = mConsumer.useSharedSwipeState();
mConsumer.onConsumerAboutToBeSwitched(); mConsumer.onConsumerAboutToBeSwitched();
mConsumer = newConsumer(newGestureState, useSharedState, event); mConsumer = newConsumer(mGestureState, newGestureState, event);
ActiveGestureLog.INSTANCE.addLog("setInputConsumer", mConsumer.getType()); ActiveGestureLog.INSTANCE.addLog("setInputConsumer", mConsumer.getType());
mUncheckedConsumer = mConsumer; mUncheckedConsumer = mConsumer;
} else if (mDeviceState.isUserUnlocked() && mMode == Mode.NO_BUTTON } else if (mDeviceState.isUserUnlocked() && mMode == Mode.NO_BUTTON
@ -461,6 +453,9 @@ public class TouchInteractionService extends Service implements
} else { } else {
mUncheckedConsumer = InputConsumer.NO_OP; mUncheckedConsumer = InputConsumer.NO_OP;
} }
// Save the current gesture state
mGestureState = newGestureState;
} }
ActiveGestureLog.INSTANCE.addLog("onMotionEvent", event.getActionMasked()); ActiveGestureLog.INSTANCE.addLog("onMotionEvent", event.getActionMasked());
@ -468,39 +463,42 @@ public class TouchInteractionService extends Service implements
TraceHelper.INSTANCE.endFlagsOverride(traceToken); TraceHelper.INSTANCE.endFlagsOverride(traceToken);
} }
private InputConsumer newConsumer(GestureState gestureState, boolean useSharedState, private InputConsumer newConsumer(GestureState previousGestureState,
MotionEvent event) { GestureState newGestureState, MotionEvent event) {
boolean canStartSystemGesture = mDeviceState.canStartSystemGesture(); boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
if (!mDeviceState.isUserUnlocked()) { if (!mDeviceState.isUserUnlocked()) {
if (canStartSystemGesture) { if (canStartSystemGesture) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps // This handles apps launched in direct boot mode (e.g. dialer) as well as apps
// launched while device is locked even after exiting direct boot mode (e.g. camera). // launched while device is locked even after exiting direct boot mode (e.g. camera).
return createDeviceLockedInputConsumer(gestureState, return createDeviceLockedInputConsumer(newGestureState,
mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT)); mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
} else { } else {
return mResetGestureInputConsumer; return mResetGestureInputConsumer;
} }
} }
// When using sharedState, bypass systemState check as this is a followup gesture and the // When there is an existing recents animation running, bypass systemState check as this is
// first gesture started in a valid system state. // a followup gesture and the first gesture started in a valid system state.
InputConsumer base = canStartSystemGesture || useSharedState InputConsumer base = canStartSystemGesture
? newBaseConsumer(gestureState, useSharedState, event) : mResetGestureInputConsumer; || previousGestureState.isRecentsAnimationRunning()
? newBaseConsumer(previousGestureState, newGestureState, event)
: mResetGestureInputConsumer;
if (mMode == Mode.NO_BUTTON) { if (mMode == Mode.NO_BUTTON) {
if (mDeviceState.canTriggerAssistantAction(event)) { if (mDeviceState.canTriggerAssistantAction(event)) {
base = new AssistantInputConsumer(this, gestureState, base, mInputMonitorCompat); base = new AssistantInputConsumer(this, newGestureState, base, mInputMonitorCompat);
} }
if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) { if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
// Put the Compose gesture as higher priority than the Assistant or base gestures // Put the Compose gesture as higher priority than the Assistant or base gestures
base = new QuickCaptureInputConsumer(this, gestureState, base, mInputMonitorCompat); base = new QuickCaptureInputConsumer(this, newGestureState, base,
mInputMonitorCompat);
} }
if (mDeviceState.isScreenPinningActive()) { if (mDeviceState.isScreenPinningActive()) {
// Note: we only allow accessibility to wrap this, and it replaces the previous // Note: we only allow accessibility to wrap this, and it replaces the previous
// base input consumer (which should be NO_OP anyway since topTaskLocked == true). // base input consumer (which should be NO_OP anyway since topTaskLocked == true).
base = new ScreenPinnedInputConsumer(this, gestureState); base = new ScreenPinnedInputConsumer(this, newGestureState);
} }
if (mDeviceState.isAccessibilityMenuAvailable()) { if (mDeviceState.isAccessibilityMenuAvailable()) {
@ -515,14 +513,10 @@ public class TouchInteractionService extends Service implements
return base; return base;
} }
private InputConsumer newBaseConsumer(GestureState gestureState, boolean useSharedState, private InputConsumer newBaseConsumer(GestureState previousGestureState,
MotionEvent event) { GestureState gestureState, MotionEvent event) {
RunningTaskInfo runningTaskInfo = TraceHelper.whitelistIpcs("getRunningTask.0", RunningTaskInfo runningTaskInfo = TraceHelper.whitelistIpcs("getRunningTask.0",
() -> mAM.getRunningTask(0)); () -> mAM.getRunningTask(0));
if (!useSharedState) {
mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */);
sSwipeSharedState.clearAllState();
}
if (mDeviceState.isKeyguardShowingOccluded()) { if (mDeviceState.isKeyguardShowingOccluded()) {
// This handles apps showing over the lockscreen (e.g. camera) // This handles apps showing over the lockscreen (e.g. camera)
return createDeviceLockedInputConsumer(gestureState, runningTaskInfo); return createDeviceLockedInputConsumer(gestureState, runningTaskInfo);
@ -543,26 +537,27 @@ public class TouchInteractionService extends Service implements
} }
} }
if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher if (previousGestureState.getFinishingRecentsAnimationTaskId() > 0) {
&& !sSwipeSharedState.recentsAnimationFinishInterrupted) {
return mResetGestureInputConsumer;
} else if (sSwipeSharedState.recentsAnimationFinishInterrupted) {
// If the finish animation was interrupted, then continue using the other activity input // If the finish animation was interrupted, then continue using the other activity input
// consumer but with the next task as the running task // consumer but with the next task as the running task
RunningTaskInfo info = new ActivityManager.RunningTaskInfo(); RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
info.id = sSwipeSharedState.nextRunningTaskId; info.id = previousGestureState.getFinishingRecentsAnimationTaskId();
return createOtherActivityInputConsumer(gestureState, event, info); return createOtherActivityInputConsumer(previousGestureState, gestureState, event,
} else if (sSwipeSharedState.goingToLauncher info);
} else if (runningTaskInfo == null) {
return mResetGestureInputConsumer;
} else if (previousGestureState.isRunningAnimationToLauncher()
|| gestureState.getActivityInterface().isResumed() || gestureState.getActivityInterface().isResumed()
|| forceOverviewInputConsumer) { || forceOverviewInputConsumer) {
return createOverviewInputConsumer(gestureState, event); return createOverviewInputConsumer(previousGestureState, gestureState, event);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() } else if (ENABLE_QUICKSTEP_LIVE_TILE.get()
&& gestureState.getActivityInterface().isInLiveTileMode()) { && gestureState.getActivityInterface().isInLiveTileMode()) {
return createOverviewInputConsumer(gestureState, event); return createOverviewInputConsumer(previousGestureState, gestureState, event);
} else if (mDeviceState.isGestureBlockedActivity(runningTaskInfo)) { } else if (mDeviceState.isGestureBlockedActivity(runningTaskInfo)) {
return mResetGestureInputConsumer; return mResetGestureInputConsumer;
} else { } else {
return createOtherActivityInputConsumer(gestureState, event, runningTaskInfo); return createOtherActivityInputConsumer(previousGestureState, gestureState, event,
runningTaskInfo);
} }
} }
@ -572,14 +567,15 @@ public class TouchInteractionService extends Service implements
&& (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0; && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
} }
private InputConsumer createOtherActivityInputConsumer(GestureState gestureState, private InputConsumer createOtherActivityInputConsumer(GestureState previousGestureState,
GestureState gestureState,
MotionEvent event, RunningTaskInfo runningTaskInfo) { MotionEvent event, RunningTaskInfo runningTaskInfo) {
final boolean shouldDefer; final boolean shouldDefer;
final BaseSwipeUpHandler.Factory factory; final BaseSwipeUpHandler.Factory factory;
if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted; shouldDefer = previousGestureState.getFinishingRecentsAnimationTaskId() < 0;
factory = mFallbackNoButtonFactory; factory = mFallbackNoButtonFactory;
} else { } else {
shouldDefer = gestureState.getActivityInterface().deferStartingActivity(mDeviceState, shouldDefer = gestureState.getActivityInterface().deferStartingActivity(mDeviceState,
@ -590,26 +586,28 @@ public class TouchInteractionService extends Service implements
final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event); final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager, return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager,
gestureState, runningTaskInfo, shouldDefer, this::onConsumerInactive, gestureState, runningTaskInfo, shouldDefer, this::onConsumerInactive,
sSwipeSharedState, mInputMonitorCompat, disableHorizontalSwipe, factory, mLogId); mInputMonitorCompat, disableHorizontalSwipe, factory);
} }
private InputConsumer createDeviceLockedInputConsumer(GestureState gestureState, private InputConsumer createDeviceLockedInputConsumer(GestureState gestureState,
RunningTaskInfo taskInfo) { RunningTaskInfo taskInfo) {
if (mMode == Mode.NO_BUTTON && taskInfo != null) { if (mMode == Mode.NO_BUTTON && taskInfo != null) {
return new DeviceLockedInputConsumer(this, mDeviceState, mTaskAnimationManager, return new DeviceLockedInputConsumer(this, mDeviceState, mTaskAnimationManager,
gestureState, sSwipeSharedState, mInputMonitorCompat, taskInfo.taskId, mLogId); gestureState, mInputMonitorCompat, taskInfo.taskId);
} else { } else {
return mResetGestureInputConsumer; return mResetGestureInputConsumer;
} }
} }
public InputConsumer createOverviewInputConsumer(GestureState gestureState, MotionEvent event) { public InputConsumer createOverviewInputConsumer(GestureState previousGestureState,
GestureState gestureState, MotionEvent event) {
BaseDraggingActivity activity = gestureState.getActivityInterface().getCreatedActivity(); BaseDraggingActivity activity = gestureState.getActivityInterface().getCreatedActivity();
if (activity == null) { if (activity == null) {
return mResetGestureInputConsumer; return mResetGestureInputConsumer;
} }
if (activity.getRootView().hasWindowFocus() || sSwipeSharedState.goingToLauncher) { if (activity.getRootView().hasWindowFocus()
|| previousGestureState.isRunningAnimationToLauncher()) {
return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat, return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
false /* startingInActivityBounds */); false /* startingInActivityBounds */);
} else { } else {
@ -704,10 +702,6 @@ public class TouchInteractionService extends Service implements
boolean resumed = mOverviewComponentObserver != null boolean resumed = mOverviewComponentObserver != null
&& mOverviewComponentObserver.getActivityInterface().isResumed(); && mOverviewComponentObserver.getActivityInterface().isResumed();
pw.println(" resumed=" + resumed); pw.println(" resumed=" + resumed);
pw.println(" useSharedState=" + mConsumer.useSharedSwipeState());
if (mConsumer.useSharedSwipeState()) {
sSwipeSharedState.dump(" ", pw);
}
pw.println(" mConsumer=" + mConsumer.getName()); pw.println(" mConsumer=" + mConsumer.getName());
pw.println("FeatureFlags:"); pw.println("FeatureFlags:");
pw.println(" APPLY_CONFIG_AT_RUNTIME=" + APPLY_CONFIG_AT_RUNTIME.get()); pw.println(" APPLY_CONFIG_AT_RUNTIME=" + APPLY_CONFIG_AT_RUNTIME.get());

View File

@ -26,11 +26,12 @@ import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.BaseActivityInterface.AnimationFactory.ShelfAnimState.HIDE; import static com.android.quickstep.BaseActivityInterface.AnimationFactory.ShelfAnimState.HIDE;
import static com.android.quickstep.BaseActivityInterface.AnimationFactory.ShelfAnimState.PEEK; import static com.android.quickstep.BaseActivityInterface.AnimationFactory.ShelfAnimState.PEEK;
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;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.HOME;
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.NEW_TASK;
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.RECENTS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import android.animation.Animator; import android.animation.Animator;
@ -70,6 +71,7 @@ import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.BaseActivityInterface.AnimationFactory; import com.android.quickstep.BaseActivityInterface.AnimationFactory;
import com.android.quickstep.BaseActivityInterface.AnimationFactory.ShelfAnimState; import com.android.quickstep.BaseActivityInterface.AnimationFactory.ShelfAnimState;
import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory; import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.inputconsumers.OverviewInputConsumer; import com.android.quickstep.inputconsumers.OverviewInputConsumer;
import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.ActiveGestureLog;
@ -138,42 +140,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private static final int LAUNCHER_UI_STATES = private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED; STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
public enum GestureEndTarget {
HOME(1, STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT, true, false,
ContainerType.WORKSPACE, false),
RECENTS(1, STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
| STATE_SCREENSHOT_VIEW_SHOWN, true, false, ContainerType.TASKSWITCHER, true),
NEW_TASK(0, STATE_START_NEW_TASK | STATE_CAPTURE_SCREENSHOT, false, true,
ContainerType.APP, true),
LAST_TASK(0, STATE_RESUME_LAST_TASK, false, true, ContainerType.APP, false);
GestureEndTarget(float endShift, int endState, boolean isLauncher, boolean canBeContinued,
int containerType, boolean recentsAttachedToAppWindow) {
this.endShift = endShift;
this.endState = endState;
this.isLauncher = isLauncher;
this.canBeContinued = canBeContinued;
this.containerType = containerType;
this.recentsAttachedToAppWindow = recentsAttachedToAppWindow;
}
/** 0 is app, 1 is overview */
public final float endShift;
/** The state to apply when we reach this final target */
public final int endState;
/** Whether the target is in the launcher activity */
public final boolean isLauncher;
/** Whether the user can start a new gesture while this one is finishing */
public final boolean canBeContinued;
/** Used to log where the user ended up after the gesture ends */
public final int containerType;
/** Whether RecentsView should be attached to the window as we animate to this target */
public final boolean recentsAttachedToAppWindow;
}
public static final long MAX_SWIPE_DURATION = 350; public static final long MAX_SWIPE_DURATION = 350;
public static final long MIN_SWIPE_DURATION = 80; public static final long MIN_SWIPE_DURATION = 80;
public static final long MIN_OVERSHOOT_DURATION = 120; public static final long MIN_OVERSHOOT_DURATION = 120;
@ -195,7 +161,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private final TaskAnimationManager mTaskAnimationManager; private final TaskAnimationManager mTaskAnimationManager;
private final GestureState mGestureState; private final GestureState mGestureState;
private GestureEndTarget mGestureEndTarget;
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
private RunningWindowAnim mRunningWindowAnim; private RunningWindowAnim mRunningWindowAnim;
private boolean mIsShelfPeeking; private boolean mIsShelfPeeking;
@ -287,6 +252,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
| STATE_GESTURE_STARTED, | STATE_GESTURE_STARTED,
this::setupLauncherUiAfterSwipeUpToRecentsAnimation); this::setupLauncherUiAfterSwipeUpToRecentsAnimation);
mGestureState.addCallback(STATE_END_TARGET_ANIMATION_FINISHED,
this::onEndTargetSet);
mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler); mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher); this::invalidateHandlerWithLauncher);
@ -338,7 +306,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
@Override @Override
protected boolean moveWindowWithRecentsScroll() { protected boolean moveWindowWithRecentsScroll() {
return mGestureEndTarget != HOME; return mGestureState.getEndTarget() != HOME;
} }
private void onLauncherStart(final T activity) { private void onLauncherStart(final T activity) {
@ -351,7 +319,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
// If we've already ended the gesture and are going home, don't prepare recents UI, // If we've already ended the gesture and are going home, don't prepare recents UI,
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL. // as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
if (mGestureEndTarget != HOME) { if (mGestureState.getEndTarget() != HOME) {
Runnable initAnimFactory = () -> { Runnable initAnimFactory = () -> {
mAnimationFactory = mActivityInterface.prepareRecentsUI(mActivity, mAnimationFactory = mActivityInterface.prepareRecentsUI(mActivity,
mWasLauncherAlreadyVisible, true, mWasLauncherAlreadyVisible, true,
@ -419,7 +387,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
mOverviewComponentObserver.getActivityInterface().switchRunningTaskViewToScreenshot( mOverviewComponentObserver.getActivityInterface().switchRunningTaskViewToScreenshot(
null, () -> { null, () -> {
mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */);
TouchInteractionService.getSwipeSharedState().clearAllState();
}); });
} else { } else {
mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */);
@ -460,13 +427,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
.getHighResLoadingState().setVisible(true); .getHighResLoadingState().setVisible(true);
} }
private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) {
float distanceToReachEdge = mDp.widthPx / 2 + taskWidth / 2 +
mContext.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
float interpolation = Math.min(1, offsetX / distanceToReachEdge);
return TaskView.getCurveScaleForInterpolation(interpolation);
}
@Override @Override
public void onMotionPauseChanged(boolean isPaused) { public void onMotionPauseChanged(boolean isPaused) {
setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION);
@ -491,9 +451,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
? null ? null
: mRecentsAnimationTargets.findTask(mRunningTaskId); : mRecentsAnimationTargets.findTask(mRunningTaskId);
final boolean recentsAttachedToAppWindow; final boolean recentsAttachedToAppWindow;
int runningTaskIndex = mRecentsView.getRunningTaskIndex(); if (mGestureState.getEndTarget() != null) {
if (mGestureEndTarget != null) { recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow;
} else if (mContinuingLastGesture } else if (mContinuingLastGesture
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) { && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
recentsAttachedToAppWindow = true; recentsAttachedToAppWindow = true;
@ -540,9 +499,10 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
} }
private void buildAnimationController() { private void buildAnimationController() {
if (mGestureEndTarget == HOME || mHasLauncherTransitionControllerStarted) { if (mGestureState.getEndTarget() == HOME || mHasLauncherTransitionControllerStarted) {
// We don't want a new mLauncherTransitionController if mGestureEndTarget == HOME (it // We don't want a new mLauncherTransitionController if
// has its own animation) or if we're already animating the current controller. // mGestureState.getEndTarget() == HOME (it has its own animation) or if we're already
// animating the current controller.
return; return;
} }
initTransitionEndpoints(mActivity.getDeviceProfile()); initTransitionEndpoints(mActivity.getDeviceProfile());
@ -599,7 +559,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
} }
private void updateLauncherTransitionProgress() { private void updateLauncherTransitionProgress() {
if (mGestureEndTarget == HOME) { if (mGestureState.getEndTarget() == HOME) {
return; return;
} }
// Normalize the progress to 0 to 1, as the animation controller will clamp it to that // Normalize the progress to 0 to 1, as the animation controller will clamp it to that
@ -709,7 +669,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
@Override @Override
protected InputConsumer createNewInputProxyHandler() { protected InputConsumer createNewInputProxyHandler() {
endRunningWindowAnim(mGestureEndTarget == HOME /* cancel */); endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
endLauncherTransitionController(); endLauncherTransitionController();
if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// Hide the task view, if not already hidden // Hide the task view, if not already hidden
@ -731,6 +691,24 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
} }
} }
private void onEndTargetSet() {
switch (mGestureState.getEndTarget()) {
case HOME:
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
break;
case RECENTS:
mStateCallback.setState(STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
| STATE_SCREENSHOT_VIEW_SHOWN);
break;
case NEW_TASK:
mStateCallback.setState(STATE_START_NEW_TASK | STATE_CAPTURE_SCREENSHOT);
break;
case LAST_TASK:
mStateCallback.setState(STATE_RESUME_LAST_TASK);
break;
}
}
private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling, private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
boolean isCancel) { boolean isCancel) {
final GestureEndTarget endTarget; final GestureEndTarget endTarget;
@ -800,7 +778,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
float currentShift = mCurrentShift.value; float currentShift = mCurrentShift.value;
final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity, final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
isFling, isCancel); isFling, isCancel);
float endShift = endTarget.endShift; float endShift = endTarget.isLauncher ? 1 : 0;
final float startShift; final float startShift;
Interpolator interpolator = DEACCEL; Interpolator interpolator = DEACCEL;
if (!isFling) { if (!isFling) {
@ -903,11 +881,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
@UiThread @UiThread
private void animateToProgressInternal(float start, float end, long duration, private void animateToProgressInternal(float start, float end, long duration,
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) { Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
mGestureEndTarget = target; // Set the state, but don't notify until the animation completes
mGestureState.setEndTarget(target, false /* isAtomic */);
maybeUpdateRecentsAttachedState(); maybeUpdateRecentsAttachedState();
if (mGestureEndTarget == HOME) { if (mGestureState.getEndTarget() == HOME) {
HomeAnimationFactory homeAnimFactory; HomeAnimationFactory homeAnimFactory;
if (mActivity != null) { if (mActivity != null) {
homeAnimFactory = mActivityInterface.prepareHomeUI(mActivity); homeAnimFactory = mActivityInterface.prepareHomeUI(mActivity);
@ -934,7 +913,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
windowAnim.addAnimatorListener(new AnimationSuccessListener() { windowAnim.addAnimatorListener(new AnimationSuccessListener() {
@Override @Override
public void onAnimationSuccess(Animator animator) { public void onAnimationSuccess(Animator animator) {
setStateOnUiThread(target.endState); // Finalize the state and notify of the change
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
} }
}); });
windowAnim.start(velocityPxPerMs); windowAnim.start(velocityPxPerMs);
@ -959,10 +939,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
// We are about to launch the current running task, so use LAST_TASK state // We are about to launch the current running task, so use LAST_TASK state
// instead of NEW_TASK. This could happen, for example, if our scroll is // instead of NEW_TASK. This could happen, for example, if our scroll is
// aborted after we determined the target to be NEW_TASK. // aborted after we determined the target to be NEW_TASK.
setStateOnUiThread(LAST_TASK.endState); mGestureState.setEndTarget(LAST_TASK);
} else {
setStateOnUiThread(target.endState);
} }
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
} }
}); });
windowAnim.start(); windowAnim.start();
@ -970,7 +949,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
} }
// Always play the entire launcher animation when going home, since it is separate from // Always play the entire launcher animation when going home, since it is separate from
// the animation that has been controlled thus far. // the animation that has been controlled thus far.
if (mGestureEndTarget == HOME) { if (mGestureState.getEndTarget() == HOME) {
start = 0; start = 0;
} }
@ -1029,14 +1008,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
} }
@Override @Override
public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { public void onConsumerAboutToBeSwitched() {
if (mGestureEndTarget != null) { if (!mGestureState.isRunningAnimationToLauncher()) {
sharedState.canGestureBeContinued = mGestureEndTarget.canBeContinued; cancelCurrentAnimation();
sharedState.goingToLauncher = mGestureEndTarget.isLauncher;
}
if (sharedState.canGestureBeContinued) {
cancelCurrentAnimation(sharedState);
} else { } else {
reset(); reset();
} }
@ -1075,7 +1049,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
* Cancels any running animation so that the active target can be overriden by a new swipe * Cancels any running animation so that the active target can be overriden by a new swipe
* handle (in case of quick switch). * handle (in case of quick switch).
*/ */
private void cancelCurrentAnimation(SwipeSharedState sharedState) { private void cancelCurrentAnimation() {
mCanceled = true; mCanceled = true;
mCurrentShift.cancelAnimation(); mCurrentShift.cancelAnimation();
if (mLauncherTransitionController != null && mLauncherTransitionController if (mLauncherTransitionController != null && mLauncherTransitionController
@ -1093,7 +1067,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
? newRunningTaskView.getTask().key.id ? newRunningTaskView.getTask().key.id
: -1; : -1;
mRecentsView.setCurrentTask(newRunningTaskId); mRecentsView.setCurrentTask(newRunningTaskId);
sharedState.setRecentsAnimationFinishInterrupted(newRunningTaskId); mGestureState.setFinishingRecentsAnimationTaskId(newRunningTaskId);
} }
} }
@ -1160,7 +1134,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
mTaskSnapshot = mRecentsAnimationController.screenshotTask(mRunningTaskId); mTaskSnapshot = mRecentsAnimationController.screenshotTask(mRunningTaskId);
} }
final TaskView taskView; final TaskView taskView;
if (mGestureEndTarget == HOME) { if (mGestureState.getEndTarget() == HOME) {
// Capture the screenshot before finishing the transition to home to ensure it's // Capture the screenshot before finishing the transition to home to ensure it's
// taken in the correct orientation, but no need to update the thumbnail. // taken in the correct orientation, but no need to update the thumbnail.
taskView = null; taskView = null;

View File

@ -22,11 +22,6 @@ public abstract class DelegateInputConsumer implements InputConsumer {
mState = STATE_INACTIVE; mState = STATE_INACTIVE;
} }
@Override
public boolean useSharedSwipeState() {
return mDelegate.useSharedSwipeState();
}
@Override @Override
public boolean allowInterceptByParent() { public boolean allowInterceptByParent() {
return mDelegate.allowInterceptByParent() && mState != STATE_ACTIVE; return mDelegate.allowInterceptByParent() && mState != STATE_ACTIVE;

View File

@ -44,7 +44,6 @@ import com.android.quickstep.LockScreenRecentsActivity;
import com.android.quickstep.MultiStateCallback; import com.android.quickstep.MultiStateCallback;
import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationTargets; import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.TaskAnimationManager; import com.android.quickstep.TaskAnimationManager;
@ -79,12 +78,10 @@ public class DeviceLockedInputConsumer implements InputConsumer,
private final TaskAnimationManager mTaskAnimationManager; private final TaskAnimationManager mTaskAnimationManager;
private final GestureState mGestureState; private final GestureState mGestureState;
private final float mTouchSlopSquared; private final float mTouchSlopSquared;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat; private final InputMonitorCompat mInputMonitorCompat;
private final PointF mTouchDown = new PointF(); private final PointF mTouchDown = new PointF();
private final AppWindowAnimationHelper mAppWindowAnimationHelper; private final AppWindowAnimationHelper mAppWindowAnimationHelper;
private int mLogId;
private final AppWindowAnimationHelper.TransformParams mTransformParams; private final AppWindowAnimationHelper.TransformParams mTransformParams;
private final Point mDisplaySize; private final Point mDisplaySize;
private final MultiStateCallback mStateCallback; private final MultiStateCallback mStateCallback;
@ -100,16 +97,13 @@ public class DeviceLockedInputConsumer implements InputConsumer,
public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState, public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState, TaskAnimationManager taskAnimationManager, GestureState gestureState,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, InputMonitorCompat inputMonitorCompat, int runningTaskId) {
int runningTaskId, int logId) {
mContext = context; mContext = context;
mDeviceState = deviceState; mDeviceState = deviceState;
mTaskAnimationManager = taskAnimationManager; mTaskAnimationManager = taskAnimationManager;
mGestureState = gestureState; mGestureState = gestureState;
mTouchSlopSquared = squaredTouchSlop(context); mTouchSlopSquared = squaredTouchSlop(context);
mSwipeSharedState = swipeSharedState;
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context); mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
mLogId = logId;
mTransformParams = new AppWindowAnimationHelper.TransformParams(); mTransformParams = new AppWindowAnimationHelper.TransformParams();
mInputMonitorCompat = inputMonitorCompat; mInputMonitorCompat = inputMonitorCompat;
mRunningTaskId = runningTaskId; mRunningTaskId = runningTaskId;
@ -216,7 +210,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
.addCategory(Intent.CATEGORY_DEFAULT) .addCategory(Intent.CATEGORY_DEFAULT)
.setComponent(new ComponentName(mContext, LockScreenRecentsActivity.class)) .setComponent(new ComponentName(mContext, LockScreenRecentsActivity.class))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mLogId); .putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId());
mTaskAnimationManager.startRecentsAnimation(mGestureState, intent, this); mTaskAnimationManager.startRecentsAnimation(mGestureState, intent, this);
} }

View File

@ -15,14 +15,14 @@
*/ */
package com.android.quickstep.inputconsumers; package com.android.quickstep.inputconsumers;
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;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import android.animation.Animator; import android.animation.Animator;
@ -35,6 +35,7 @@ import android.graphics.PointF;
import android.graphics.RectF; import android.graphics.RectF;
import android.os.Bundle; import android.os.Bundle;
import android.util.ArrayMap;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorPlaybackController;
@ -43,13 +44,13 @@ import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory;
import com.android.quickstep.AnimatedFloat; import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.BaseSwipeUpHandler;
import com.android.quickstep.GestureState; import com.android.quickstep.GestureState;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.InputConsumer; import com.android.quickstep.InputConsumer;
import com.android.quickstep.MultiStateCallback; import com.android.quickstep.MultiStateCallback;
import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.OverviewComponentObserver;
import com.android.quickstep.RecentsActivity; import com.android.quickstep.RecentsActivity;
import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsModel; import com.android.quickstep.RecentsModel;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.RecentsAnimationTargets; import com.android.quickstep.RecentsAnimationTargets;
@ -83,27 +84,23 @@ public class FallbackNoButtonInputConsumer extends
private static final int STATE_APP_CONTROLLER_RECEIVED = private static final int STATE_APP_CONTROLLER_RECEIVED =
getFlagForIndex(4, "STATE_APP_CONTROLLER_RECEIVED"); getFlagForIndex(4, "STATE_APP_CONTROLLER_RECEIVED");
public enum GestureEndTarget { public static class EndTargetAnimationParams {
HOME(3, 100, 1),
RECENTS(1, 300, 0),
LAST_TASK(0, 150, 1),
NEW_TASK(0, 150, 1);
private final float mEndProgress; private final float mEndProgress;
private final long mDurationMultiplier; private final long mDurationMultiplier;
private final float mLauncherAlpha; private final float mLauncherAlpha;
GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) { EndTargetAnimationParams(float endProgress, long durationMultiplier, float launcherAlpha) {
mEndProgress = endProgress; mEndProgress = endProgress;
mDurationMultiplier = durationMultiplier; mDurationMultiplier = durationMultiplier;
mLauncherAlpha = launcherAlpha; mLauncherAlpha = launcherAlpha;
} }
} }
private static ArrayMap<GestureEndTarget, EndTargetAnimationParams>
mEndTargetAnimationParams = new ArrayMap();
private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged);
private boolean mIsMotionPaused = false; private boolean mIsMotionPaused = false;
private GestureEndTarget mEndTarget;
private final boolean mInQuickSwitchMode; private final boolean mInQuickSwitchMode;
private final boolean mContinuingLastGesture; private final boolean mContinuingLastGesture;
@ -136,6 +133,12 @@ public class FallbackNoButtonInputConsumer extends
mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
} }
// Going home has an extra long progress to ensure that it animates into the screen
mEndTargetAnimationParams.put(HOME, new EndTargetAnimationParams(3, 100, 1));
mEndTargetAnimationParams.put(RECENTS, new EndTargetAnimationParams(1, 300, 0));
mEndTargetAnimationParams.put(LAST_TASK, new EndTargetAnimationParams(0, 150, 1));
mEndTargetAnimationParams.put(NEW_TASK, new EndTargetAnimationParams(0, 150, 1));
initStateCallbacks(); initStateCallbacks();
} }
@ -161,7 +164,7 @@ public class FallbackNoButtonInputConsumer extends
} }
private void onLauncherAlphaChanged() { private void onLauncherAlphaChanged() {
if (mRecentsAnimationTargets != null && mEndTarget == null) { if (mRecentsAnimationTargets != null && mGestureState.getEndTarget() == null) {
applyTransformUnchecked(); applyTransformUnchecked();
} }
} }
@ -247,7 +250,7 @@ public class FallbackNoButtonInputConsumer extends
@Override @Override
public void onGestureCancelled() { public void onGestureCancelled() {
updateDisplacement(0); updateDisplacement(0);
mEndTarget = LAST_TASK; mGestureState.setEndTarget(LAST_TASK);
setStateOnUiThread(STATE_GESTURE_CANCELLED); setStateOnUiThread(STATE_GESTURE_CANCELLED);
} }
@ -256,28 +259,29 @@ public class FallbackNoButtonInputConsumer extends
mEndVelocityPxPerMs.set(0, velocity.y / 1000); mEndVelocityPxPerMs.set(0, velocity.y / 1000);
if (mInQuickSwitchMode) { if (mInQuickSwitchMode) {
// For now set it to non-null, it will be reset before starting the animation // For now set it to non-null, it will be reset before starting the animation
mEndTarget = LAST_TASK; mGestureState.setEndTarget(LAST_TASK);
} else { } else {
float flingThreshold = mContext.getResources() float flingThreshold = mContext.getResources()
.getDimension(R.dimen.quickstep_fling_threshold_velocity); .getDimension(R.dimen.quickstep_fling_threshold_velocity);
boolean isFling = Math.abs(endVelocity) > flingThreshold; boolean isFling = Math.abs(endVelocity) > flingThreshold;
if (isFling) { if (isFling) {
mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; mGestureState.setEndTarget(endVelocity < 0 ? HOME : LAST_TASK);
} else if (mIsMotionPaused) { } else if (mIsMotionPaused) {
mEndTarget = RECENTS; mGestureState.setEndTarget(RECENTS);
} else { } else {
mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; mGestureState.setEndTarget(mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW
? HOME
: LAST_TASK);
} }
} }
setStateOnUiThread(STATE_GESTURE_COMPLETED); setStateOnUiThread(STATE_GESTURE_COMPLETED);
} }
@Override @Override
public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { public void onConsumerAboutToBeSwitched() {
if (mInQuickSwitchMode && mEndTarget != null) { if (mInQuickSwitchMode && mGestureState.getEndTarget() != null) {
sharedState.canGestureBeContinued = true; mGestureState.setEndTarget(HOME);
sharedState.goingToLauncher = false;
mCanceled = true; mCanceled = true;
mCurrentShift.cancelAnimation(); mCurrentShift.cancelAnimation();
@ -293,7 +297,7 @@ public class FallbackNoButtonInputConsumer extends
? newRunningTaskView.getTask().key.id ? newRunningTaskView.getTask().key.id
: -1; : -1;
mRecentsView.setCurrentTask(newRunningTaskId); mRecentsView.setCurrentTask(newRunningTaskId);
sharedState.setRecentsAnimationFinishInterrupted(newRunningTaskId); mGestureState.setFinishingRecentsAnimationTaskId(newRunningTaskId);
} }
mRecentsView.setOnScrollChangeListener(null); mRecentsView.setOnScrollChangeListener(null);
} }
@ -319,7 +323,7 @@ public class FallbackNoButtonInputConsumer extends
} }
private void finishAnimationTargetSetAnimationComplete() { private void finishAnimationTargetSetAnimationComplete() {
switch (mEndTarget) { switch (mGestureState.getEndTarget()) {
case HOME: { case HOME: {
if (mSwipeUpOverHome) { if (mSwipeUpOverHome) {
mRecentsAnimationController.finish(false, null, false); mRecentsAnimationController.finish(false, null, false);
@ -370,17 +374,20 @@ public class FallbackNoButtonInputConsumer extends
// Recalculate the end target, some views might have been initialized after // Recalculate the end target, some views might have been initialized after
// gesture has ended. // gesture has ended.
if (mRecentsView == null || !hasTargets()) { if (mRecentsView == null || !hasTargets()) {
mEndTarget = LAST_TASK; mGestureState.setEndTarget(LAST_TASK);
} else { } else {
final int runningTaskIndex = mRecentsView.getRunningTaskIndex(); final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
final int taskToLaunch = mRecentsView.getNextPage(); final int taskToLaunch = mRecentsView.getNextPage();
mEndTarget = (runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex) mGestureState.setEndTarget(
? NEW_TASK : LAST_TASK; (runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex)
? NEW_TASK
: LAST_TASK);
} }
} }
float endProgress = mEndTarget.mEndProgress; EndTargetAnimationParams params = mEndTargetAnimationParams.get(mGestureState.getEndTarget());
long duration = (long) (mEndTarget.mDurationMultiplier * float endProgress = params.mEndProgress;
long duration = (long) (params.mDurationMultiplier *
Math.abs(endProgress - mCurrentShift.value)); Math.abs(endProgress - mCurrentShift.value));
if (mRecentsView != null) { if (mRecentsView != null) {
duration = Math.max(duration, mRecentsView.getScroller().getDuration()); duration = Math.max(duration, mRecentsView.getScroller().getDuration());
@ -395,7 +402,7 @@ public class FallbackNoButtonInputConsumer extends
} }
}; };
if (mEndTarget == HOME && !mRunningOverHome) { if (mGestureState.getEndTarget() == HOME && !mRunningOverHome) {
RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration); RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration);
anim.addAnimatorListener(endListener); anim.addAnimatorListener(endListener);
anim.start(mEndVelocityPxPerMs); anim.start(mEndVelocityPxPerMs);
@ -404,7 +411,7 @@ public class FallbackNoButtonInputConsumer extends
AnimatorSet anim = new AnimatorSet(); AnimatorSet anim = new AnimatorSet();
anim.play(mLauncherAlpha.animateToValue( anim.play(mLauncherAlpha.animateToValue(
mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); mLauncherAlpha.value, params.mLauncherAlpha));
anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress));
anim.setDuration(duration); anim.setDuration(duration);

View File

@ -54,7 +54,6 @@ import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer; import com.android.quickstep.InputConsumer;
import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.TaskAnimationManager; import com.android.quickstep.TaskAnimationManager;
@ -85,7 +84,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
private RecentsAnimationCallbacks mActiveCallbacks; private RecentsAnimationCallbacks mActiveCallbacks;
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
private final RunningTaskInfo mRunningTask; private final RunningTaskInfo mRunningTask;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat; private final InputMonitorCompat mInputMonitorCompat;
private final SysUINavigationMode.Mode mMode; private final SysUINavigationMode.Mode mMode;
private final BaseActivityInterface mActivityInterface; private final BaseActivityInterface mActivityInterface;
@ -126,16 +124,14 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
ActivityManagerWrapper.getInstance().cancelRecentsAnimation( ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
true /* restoreHomeStackPosition */); true /* restoreHomeStackPosition */);
}; };
private int mLogId;
public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState, public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState, TaskAnimationManager taskAnimationManager, GestureState gestureState,
RunningTaskInfo runningTaskInfo, boolean isDeferredDownTarget, RunningTaskInfo runningTaskInfo, boolean isDeferredDownTarget,
Consumer<OtherActivityInputConsumer> onCompleteCallback, Consumer<OtherActivityInputConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, InputMonitorCompat inputMonitorCompat, boolean disableHorizontalSwipe,
boolean disableHorizontalSwipe, Factory handlerFactory, int logId) { Factory handlerFactory) {
super(base); super(base);
mLogId = logId;
mDeviceState = deviceState; mDeviceState = deviceState;
mTaskAnimationManager = taskAnimationManager; mTaskAnimationManager = taskAnimationManager;
mGestureState = gestureState; mGestureState = gestureState;
@ -154,7 +150,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning(); boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
mSwipeSharedState = swipeSharedState;
mNavBarPosition = new NavBarPosition(base); mNavBarPosition = new NavBarPosition(base);
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop(); mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
@ -347,7 +342,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
notifyGestureStarted(); notifyGestureStarted();
} else { } else {
Intent intent = mInteractionHandler.getLaunchIntent(); Intent intent = mInteractionHandler.getLaunchIntent();
intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mLogId); intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId());
mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent, mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent,
mInteractionHandler); mInteractionHandler);
} }
@ -404,7 +399,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
// The consumer is being switched while we are active. Set up the shared state to be // The consumer is being switched while we are active. Set up the shared state to be
// used by the next animation // used by the next animation
removeListener(); removeListener();
mInteractionHandler.onConsumerAboutToBeSwitched(mSwipeSharedState); mInteractionHandler.onConsumerAboutToBeSwitched();
} }
} }
@ -432,11 +427,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
} }
} }
@Override
public boolean useSharedSwipeState() {
return mInteractionHandler != null;
}
@Override @Override
public boolean allowInterceptByParent() { public boolean allowInterceptByParent() {
return !mPassedPilferInputSlop; return !mPassedPilferInputSlop;

View File

@ -42,7 +42,6 @@ public class ResetGestureInputConsumer implements InputConsumer {
if (ev.getAction() == MotionEvent.ACTION_DOWN if (ev.getAction() == MotionEvent.ACTION_DOWN
&& mTaskAnimationManager.isRecentsAnimationRunning()) { && mTaskAnimationManager.isRecentsAnimationRunning()) {
mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */); mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */);
TouchInteractionService.getSwipeSharedState().clearAllState();
} }
} }
} }

View File

@ -15,8 +15,12 @@
*/ */
package com.android.quickstep; package com.android.quickstep;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.recents.model.ThumbnailData;
import java.util.ArrayList;
/** /**
* Manages the state for an active system gesture, listens for events from the system and Launcher, * Manages the state for an active system gesture, listens for events from the system and Launcher,
@ -24,30 +28,202 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
*/ */
public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationListener { public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationListener {
// Needed to interact with the current activity /**
private BaseActivityInterface mActivityInterface; * Defines the end targets of a gesture and the associated state.
*/
public enum GestureEndTarget {
HOME(true, ContainerType.WORKSPACE, false),
public GestureState(BaseActivityInterface activityInterface) { RECENTS(true, ContainerType.TASKSWITCHER, true),
mActivityInterface = activityInterface;
NEW_TASK(false, ContainerType.APP, true),
LAST_TASK(false, ContainerType.APP, false);
GestureEndTarget(boolean isLauncher, int containerType,
boolean recentsAttachedToAppWindow) {
this.isLauncher = isLauncher;
this.containerType = containerType;
this.recentsAttachedToAppWindow = recentsAttachedToAppWindow;
} }
/** Whether the target is in the launcher activity. Implicitly, if the end target is going
to Launcher, then we can not interrupt the animation to start another gesture. */
public final boolean isLauncher;
/** Used to log where the user ended up after the gesture ends */
public final int containerType;
/** Whether RecentsView should be attached to the window as we animate to this target */
public final boolean recentsAttachedToAppWindow;
}
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
private static int FLAG_COUNT = 0;
private static int getFlagForIndex(String name) {
if (DEBUG_STATES) {
STATE_NAMES.add(name);
}
int index = 1 << FLAG_COUNT;
FLAG_COUNT++;
return index;
}
// Called when the end target as been set
public static final int STATE_END_TARGET_SET =
getFlagForIndex("STATE_END_TARGET_SET");
// Called when the end target animation has finished
public static final int STATE_END_TARGET_ANIMATION_FINISHED =
getFlagForIndex("STATE_END_TARGET_ANIMATION_FINISHED");
// Called when the recents animation has been requested to start
public static final int STATE_RECENTS_ANIMATION_INITIALIZED =
getFlagForIndex("STATE_RECENTS_ANIMATION_INITIALIZED");
// Called when the recents animation is started and the TaskAnimationManager has been updated
// with the controller and targets
public static final int STATE_RECENTS_ANIMATION_STARTED =
getFlagForIndex("STATE_RECENTS_ANIMATION_STARTED");
// Called when the recents animation is canceled
public static final int STATE_RECENTS_ANIMATION_CANCELED =
getFlagForIndex("STATE_RECENTS_ANIMATION_CANCELED");
// Called when the recents animation finishes
public static final int STATE_RECENTS_ANIMATION_FINISHED =
getFlagForIndex("STATE_RECENTS_ANIMATION_FINISHED");
// Always called when the recents animation ends (regardless of cancel or finish)
public static final int STATE_RECENTS_ANIMATION_ENDED =
getFlagForIndex("STATE_RECENTS_ANIMATION_ENDED");
// Needed to interact with the current activity
private final BaseActivityInterface mActivityInterface;
private final MultiStateCallback mStateCallback;
private final int mGestureId;
private GestureEndTarget mEndTarget;
// TODO: This can be removed once we stop finishing the animation when starting a new task
private int mFinishingRecentsAnimationTaskId = -1;
public GestureState(BaseActivityInterface activityInterface, int gestureId) {
mActivityInterface = activityInterface;
mGestureId = gestureId;
mStateCallback = new MultiStateCallback(STATE_NAMES.toArray(new String[0]));
}
public GestureState() {
// Do nothing, only used for initializing the gesture state prior to user unlock
mActivityInterface = null;
mGestureId = -1;
mStateCallback = new MultiStateCallback(STATE_NAMES.toArray(new String[0]));
}
/**
* Sets the given {@param stateFlag}s.
*/
public void setState(int stateFlag) {
mStateCallback.setState(stateFlag);
}
/**
* Adds a callback for when the states matching the given {@param stateMask} is set.
*/
public void addCallback(int stateMask, Runnable callback) {
mStateCallback.addCallback(stateMask, callback);
}
/**
* @return the interface to the activity handing the UI updates for this gesture.
*/
public <T extends BaseDraggingActivity> BaseActivityInterface<T> getActivityInterface() { public <T extends BaseDraggingActivity> BaseActivityInterface<T> getActivityInterface() {
return mActivityInterface; return mActivityInterface;
} }
/**
* @return the id for this particular gesture.
*/
public int getGestureId() {
return mGestureId;
}
/**
* @return the end target for this gesture (if known).
*/
public GestureEndTarget getEndTarget() {
return mEndTarget;
}
/**
* @return whether the current gesture is still running a recents animation to a state in the
* Launcher or Recents activity.
*/
public boolean isRunningAnimationToLauncher() {
return isRecentsAnimationRunning() && mEndTarget != null && mEndTarget.isLauncher;
}
/**
* Sets the end target of this gesture and immediately notifies the state changes.
*/
public void setEndTarget(GestureEndTarget target) {
setEndTarget(target, true /* isAtomic */);
}
/**
* Sets the end target of this gesture, but if {@param isAtomic} is {@code false}, then the
* caller must explicitly set {@link #STATE_END_TARGET_ANIMATION_FINISHED} themselves.
*/
public void setEndTarget(GestureEndTarget target, boolean isAtomic) {
mEndTarget = target;
mStateCallback.setState(STATE_END_TARGET_SET);
if (isAtomic) {
mStateCallback.setState(STATE_END_TARGET_ANIMATION_FINISHED);
}
}
/**
* @return the id for the task that was about to be launched following the finish of the recents
* animation. Only defined between when the finish-recents call was made and the launch
* activity call is made.
*/
public int getFinishingRecentsAnimationTaskId() {
return mFinishingRecentsAnimationTaskId;
}
/**
* Sets the id for the task will be launched after the recents animation is finished. Once the
* animation has finished then the id will be reset to -1.
*/
public void setFinishingRecentsAnimationTaskId(int taskId) {
mFinishingRecentsAnimationTaskId = taskId;
mStateCallback.addCallback(STATE_RECENTS_ANIMATION_FINISHED, () -> {
mFinishingRecentsAnimationTaskId = -1;
});
}
/**
* @return whether the recents animation is started but not yet ended
*/
public boolean isRecentsAnimationRunning() {
return mStateCallback.hasStates(STATE_RECENTS_ANIMATION_INITIALIZED) &&
!mStateCallback.hasStates(STATE_RECENTS_ANIMATION_ENDED);
}
@Override @Override
public void onRecentsAnimationStart(RecentsAnimationController controller, public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) { RecentsAnimationTargets targets) {
// To be implemented mStateCallback.setState(STATE_RECENTS_ANIMATION_STARTED);
} }
@Override @Override
public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) { public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
// To be implemented mStateCallback.setState(STATE_RECENTS_ANIMATION_CANCELED);
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
} }
@Override @Override
public void onRecentsAnimationFinished(RecentsAnimationController controller) { public void onRecentsAnimationFinished(RecentsAnimationController controller) {
// To be implemented mStateCallback.setState(STATE_RECENTS_ANIMATION_FINISHED);
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
} }
} }

View File

@ -52,10 +52,6 @@ public interface InputConsumer {
int getType(); int getType();
default boolean useSharedSwipeState() {
return false;
}
/** /**
* Returns true if the user has crossed the threshold for it to be an explicit action. * Returns true if the user has crossed the threshold for it to be an explicit action.
*/ */
@ -65,6 +61,8 @@ public interface InputConsumer {
/** /**
* Called by the event queue when the consumer is about to be switched to a new consumer. * Called by the event queue when the consumer is about to be switched to a new consumer.
* Consumers should update the state accordingly here before the state is passed to the new
* consumer.
*/ */
default void onConsumerAboutToBeSwitched() { } default void onConsumerAboutToBeSwitched() { }

View File

@ -17,6 +17,7 @@ package com.android.quickstep;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
import android.content.Intent; import android.content.Intent;
import android.util.Log; import android.util.Log;
@ -95,6 +96,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
mCallbacks.addListener(listener); mCallbacks.addListener(listener);
UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
.startRecentsActivity(intent, null, mCallbacks, null, null)); .startRecentsActivity(intent, null, mCallbacks, null, null));
gestureState.setState(STATE_RECENTS_ANIMATION_INITIALIZED);
return mCallbacks; return mCallbacks;
} }