6/ Update recents animation classes to have their respective responsibilities
- RecentsAnimationTargets: manages information about the targets only
RecentsAnimationCallbacks: manages callbacks from WM about the animation
RecentsAnimationWrapper: manages calls into WM to update the animation
(to be renamed accordingly in a follow up CL)
- Create the Callbacks as a part of starting the recents animation, and
have the callbacks create the controller wrapper and the targets, which
are both notified to the listeners through the callbacks.
- Instead of passing through a callback for recents animation finished,
have it be a part of the recents animation callbacks.
Bug: 141886704
Change-Id: I4ff26a175654e82efe059fa74d1f310e93961dc9
This commit is contained in:
@@ -64,15 +64,16 @@ import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.RemoteAnimationTargets;
|
||||
import com.android.quickstep.util.RecentsAnimationTargets;
|
||||
import com.android.quickstep.util.RecentsAnimationCallbacks.RecentsAnimationListener;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -115,7 +116,13 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
|
||||
|
||||
protected final ActivityInitListener mActivityInitListener;
|
||||
protected final RecentsAnimationWrapper mRecentsAnimationWrapper;
|
||||
protected final InputConsumerController mInputConsumer;
|
||||
|
||||
protected RecentsAnimationWrapper mRecentsAnimationWrapper;
|
||||
protected RecentsAnimationTargets mRecentsAnimationTargets;
|
||||
|
||||
// Callbacks to be made once the recents animation starts
|
||||
private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>();
|
||||
|
||||
protected T mActivity;
|
||||
protected Q mRecentsView;
|
||||
@@ -140,8 +147,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
mActivityInitListener =
|
||||
mActivityControlHelper.createActivityInitListener(this::onActivityInit);
|
||||
mRunningTaskId = runningTaskId;
|
||||
mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer,
|
||||
this::createNewInputProxyHandler);
|
||||
mInputConsumer = inputConsumer;
|
||||
mMode = SysUINavigationMode.getMode(context);
|
||||
|
||||
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
|
||||
@@ -210,8 +216,8 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
protected void linkRecentsViewScroll() {
|
||||
SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, applier -> {
|
||||
mTransformParams.setSyncTransactionApplier(applier);
|
||||
mRecentsAnimationWrapper.runOnInit(() ->
|
||||
mRecentsAnimationWrapper.targetSet.addDependentTransactionApplier(applier));
|
||||
runOnRecentsAnimationStart(() ->
|
||||
mRecentsAnimationTargets.addDependentTransactionApplier(applier));
|
||||
});
|
||||
|
||||
mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
|
||||
@@ -219,8 +225,10 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
updateFinalShift();
|
||||
}
|
||||
});
|
||||
mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper);
|
||||
mRecentsView.setAppWindowAnimationHelper(mAppWindowAnimationHelper);
|
||||
runOnRecentsAnimationStart(() ->
|
||||
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationWrapper,
|
||||
mRecentsAnimationTargets));
|
||||
}
|
||||
|
||||
protected void startNewTask(int successStateFlag, Consumer<Boolean> resultCallback) {
|
||||
@@ -256,8 +264,30 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given {@param action} if the recents animation has already started, or queues it to
|
||||
* be run when it is next started.
|
||||
*/
|
||||
protected void runOnRecentsAnimationStart(Runnable action) {
|
||||
if (mRecentsAnimationTargets == null) {
|
||||
mRecentsAnimationStartCallbacks.add(action);
|
||||
} else {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the recents animation has started and there are valid app targets.
|
||||
*/
|
||||
protected boolean hasTargets() {
|
||||
return mRecentsAnimationTargets != null && mRecentsAnimationTargets.hasTargets();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
|
||||
public void onRecentsAnimationStart(RecentsAnimationWrapper recentsAnimationController,
|
||||
RecentsAnimationTargets targetSet) {
|
||||
mRecentsAnimationWrapper = recentsAnimationController;
|
||||
mRecentsAnimationTargets = targetSet;
|
||||
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
|
||||
final Rect overviewStackBounds;
|
||||
RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
|
||||
@@ -281,7 +311,25 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
mAppWindowAnimationHelper.prepareAnimation(dp, false /* isOpening */);
|
||||
initTransitionEndpoints(dp);
|
||||
|
||||
mRecentsAnimationWrapper.setController(targetSet);
|
||||
// Notify when the animation starts
|
||||
if (!mRecentsAnimationStartCallbacks.isEmpty()) {
|
||||
for (Runnable action : new ArrayList<>(mRecentsAnimationStartCallbacks)) {
|
||||
action.run();
|
||||
}
|
||||
mRecentsAnimationStartCallbacks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
mRecentsAnimationWrapper = null;
|
||||
mRecentsAnimationTargets = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationFinished(RecentsAnimationWrapper controller) {
|
||||
mRecentsAnimationWrapper = null;
|
||||
mRecentsAnimationTargets = null;
|
||||
}
|
||||
|
||||
private Rect getStackBounds(DeviceProfile dp) {
|
||||
@@ -370,7 +418,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
mTransformParams.setProgress(shift)
|
||||
.setOffsetX(offsetX)
|
||||
.setOffsetScale(offsetScale)
|
||||
.setTargetSet(mRecentsAnimationWrapper.targetSet)
|
||||
.setTargetSet(mRecentsAnimationTargets)
|
||||
.setLauncherOnTop(true);
|
||||
mAppWindowAnimationHelper.applyTransform(mTransformParams);
|
||||
}
|
||||
@@ -388,11 +436,10 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
*/
|
||||
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
||||
HomeAnimationFactory homeAnimationFactory) {
|
||||
final RemoteAnimationTargets targetSet = mRecentsAnimationWrapper.targetSet;
|
||||
final RectF startRect = new RectF(
|
||||
mAppWindowAnimationHelper.applyTransform(
|
||||
mTransformParams.setProgress(startProgress)
|
||||
.setTargetSet(targetSet)
|
||||
.setTargetSet(mRecentsAnimationTargets)
|
||||
.setLauncherOnTop(false)));
|
||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||
|
||||
|
||||
+93
-67
@@ -18,6 +18,8 @@ package com.android.quickstep;
|
||||
import static android.view.MotionEvent.ACTION_CANCEL;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
@@ -29,10 +31,14 @@ import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.quickstep.inputconsumers.InputConsumer;
|
||||
import com.android.quickstep.util.RecentsAnimationCallbacks;
|
||||
import com.android.quickstep.util.RecentsAnimationTargets;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
@@ -42,56 +48,82 @@ public class RecentsAnimationWrapper {
|
||||
|
||||
private static final String TAG = "RecentsAnimationWrapper";
|
||||
|
||||
// A list of callbacks to run when we receive the recents animation target. There are different
|
||||
// than the state callbacks as these run on the current worker thread.
|
||||
private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
|
||||
|
||||
public RecentsAnimationTargets targetSet;
|
||||
private final RecentsAnimationControllerCompat mController;
|
||||
private final Consumer<RecentsAnimationWrapper> mOnFinishedListener;
|
||||
private final boolean mShouldMinimizeSplitScreen;
|
||||
|
||||
private boolean mWindowThresholdCrossed = false;
|
||||
|
||||
private final InputConsumerController mInputConsumerController;
|
||||
private final Supplier<InputConsumer> mInputProxySupplier;
|
||||
|
||||
private InputConsumerController mInputConsumerController;
|
||||
private Supplier<InputConsumer> mInputProxySupplier;
|
||||
private InputConsumer mInputConsumer;
|
||||
private boolean mTouchInProgress;
|
||||
|
||||
private boolean mFinishPending;
|
||||
|
||||
public RecentsAnimationWrapper(InputConsumerController inputConsumerController,
|
||||
Supplier<InputConsumer> inputProxySupplier) {
|
||||
mInputConsumerController = inputConsumerController;
|
||||
mInputProxySupplier = inputProxySupplier;
|
||||
public RecentsAnimationWrapper(RecentsAnimationControllerCompat controller,
|
||||
boolean shouldMinimizeSplitScreen,
|
||||
Consumer<RecentsAnimationWrapper> onFinishedListener) {
|
||||
mController = controller;
|
||||
mOnFinishedListener = onFinishedListener;
|
||||
mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen;
|
||||
|
||||
setWindowThresholdCrossed(mWindowThresholdCrossed);
|
||||
}
|
||||
|
||||
public boolean hasTargets() {
|
||||
return targetSet != null && targetSet.hasTargets();
|
||||
/**
|
||||
* Synchronously takes a screenshot of the task with the given {@param taskId} if the task is
|
||||
* currently being animated.
|
||||
*/
|
||||
public ThumbnailData screenshotTask(int taskId) {
|
||||
return mController != null ? mController.screenshotTask(taskId) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the gesture has crossed the window boundary threshold and system UI can be
|
||||
* update the represent the window behind
|
||||
*/
|
||||
public void setWindowThresholdCrossed(boolean windowThresholdCrossed) {
|
||||
if (mWindowThresholdCrossed != windowThresholdCrossed) {
|
||||
mWindowThresholdCrossed = windowThresholdCrossed;
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
mController.setAnimationTargetsBehindSystemBars(!windowThresholdCrossed);
|
||||
if (mShouldMinimizeSplitScreen && windowThresholdCrossed) {
|
||||
// NOTE: As a workaround for conflicting animations (Launcher animating the task
|
||||
// leash, and SystemUI resizing the docked stack, which resizes the task), we
|
||||
// currently only set the minimized mode, and not the inverse.
|
||||
// TODO: Synchronize the minimize animation with the launcher animation
|
||||
mController.setSplitScreenMinimized(windowThresholdCrossed);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the controller that we want to defer cancel until the next app transition starts.
|
||||
* If {@param screenshot} is set, then we will receive a screenshot on the next
|
||||
* {@link RecentsAnimationCallbacks#onAnimationCanceled(ThumbnailData)} and we must also call
|
||||
* {@link #cleanupScreenshot()} when that screenshot is no longer used.
|
||||
*/
|
||||
public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
|
||||
mController.setDeferCancelUntilNextTransition(defer, screenshot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the screenshot previously returned from
|
||||
* {@link RecentsAnimationCallbacks#onAnimationCanceled(ThumbnailData)}.
|
||||
*/
|
||||
public void cleanupScreenshot() {
|
||||
UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot());
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public synchronized void setController(RecentsAnimationTargets targetSet) {
|
||||
Preconditions.assertUIThread();
|
||||
this.targetSet = targetSet;
|
||||
|
||||
if (targetSet == null) {
|
||||
return;
|
||||
}
|
||||
targetSet.setWindowThresholdCrossed(mWindowThresholdCrossed);
|
||||
|
||||
if (!mCallbacks.isEmpty()) {
|
||||
for (Runnable action : new ArrayList<>(mCallbacks)) {
|
||||
action.run();
|
||||
}
|
||||
mCallbacks.clear();
|
||||
}
|
||||
public void finishAnimationToHome() {
|
||||
finishAndClear(true /* toRecents */, null, false /* sendUserLeaveHint */);
|
||||
}
|
||||
|
||||
public synchronized void runOnInit(Runnable action) {
|
||||
if (targetSet == null) {
|
||||
mCallbacks.add(action);
|
||||
} else {
|
||||
action.run();
|
||||
}
|
||||
@UiThread
|
||||
public void finishAnimationToApp() {
|
||||
finishAndClear(false /* toRecents */, null, false /* sendUserLeaveHint */);
|
||||
}
|
||||
|
||||
/** See {@link #finish(boolean, Runnable, boolean)} */
|
||||
@@ -127,34 +159,36 @@ public class RecentsAnimationWrapper {
|
||||
|
||||
private void finishAndClear(boolean toRecents, Runnable onFinishComplete,
|
||||
boolean sendUserLeaveHint) {
|
||||
RecentsAnimationTargets controller = targetSet;
|
||||
targetSet = null;
|
||||
disableInputProxy();
|
||||
if (controller != null) {
|
||||
controller.finishController(toRecents, onFinishComplete, sendUserLeaveHint);
|
||||
}
|
||||
finishController(toRecents, onFinishComplete, sendUserLeaveHint);
|
||||
}
|
||||
|
||||
public void enableInputConsumer() {
|
||||
if (targetSet != null) {
|
||||
targetSet.enableInputConsumer();
|
||||
}
|
||||
@UiThread
|
||||
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
|
||||
mOnFinishedListener.accept(this);
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
mController.setInputConsumerEnabled(false);
|
||||
mController.finish(toRecents, sendUserLeaveHint);
|
||||
if (callback != null) {
|
||||
MAIN_EXECUTOR.execute(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the gesture has crossed the window boundary threshold and system UI can be
|
||||
* update the represent the window behind
|
||||
* Enables the input consumer to start intercepting touches in the app window.
|
||||
*/
|
||||
public void setWindowThresholdCrossed(boolean windowThresholdCrossed) {
|
||||
if (mWindowThresholdCrossed != windowThresholdCrossed) {
|
||||
mWindowThresholdCrossed = windowThresholdCrossed;
|
||||
if (targetSet != null) {
|
||||
targetSet.setWindowThresholdCrossed(windowThresholdCrossed);
|
||||
}
|
||||
}
|
||||
public void enableInputConsumer() {
|
||||
UI_HELPER_EXECUTOR.submit(() -> {
|
||||
mController.hideCurrentInputMethod();
|
||||
mController.setInputConsumerEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void enableInputProxy() {
|
||||
public void enableInputProxy(InputConsumerController inputConsumerController,
|
||||
Supplier<InputConsumer> inputProxySupplier) {
|
||||
mInputProxySupplier = inputProxySupplier;
|
||||
mInputConsumerController = inputConsumerController;
|
||||
mInputConsumerController.setInputListener(this::onInputConsumerEvent);
|
||||
}
|
||||
|
||||
@@ -165,7 +199,9 @@ public class RecentsAnimationWrapper {
|
||||
mInputConsumer.onMotionEvent(dummyCancel);
|
||||
dummyCancel.recycle();
|
||||
}
|
||||
mInputConsumerController.setInputListener(null);
|
||||
if (mInputConsumerController != null) {
|
||||
mInputConsumerController.setInputListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onInputConsumerEvent(InputEvent ev) {
|
||||
@@ -214,14 +250,4 @@ public class RecentsAnimationWrapper {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
|
||||
if (targetSet != null) {
|
||||
targetSet.controller.setDeferCancelUntilNextTransition(defer, screenshot);
|
||||
}
|
||||
}
|
||||
|
||||
public RecentsAnimationTargets getController() {
|
||||
return targetSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,9 @@ public class SwipeSharedState implements RecentsAnimationListener {
|
||||
private OverviewComponentObserver mOverviewComponentObserver;
|
||||
|
||||
private RecentsAnimationCallbacks mRecentsAnimationListener;
|
||||
private RecentsAnimationWrapper mLastRecentsAnimationController;
|
||||
private RecentsAnimationTargets mLastAnimationTarget;
|
||||
|
||||
// TODO: Remove
|
||||
private Runnable mRecentsAnimationCanceledCallback;
|
||||
|
||||
private boolean mLastAnimationCancelled = false;
|
||||
private boolean mLastAnimationRunning = false;
|
||||
|
||||
@@ -57,13 +55,35 @@ public class SwipeSharedState implements RecentsAnimationListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
|
||||
public final void onRecentsAnimationStart(RecentsAnimationWrapper controller,
|
||||
RecentsAnimationTargets targetSet) {
|
||||
mLastRecentsAnimationController = controller;
|
||||
mLastAnimationTarget = targetSet;
|
||||
|
||||
mLastAnimationCancelled = false;
|
||||
mLastAnimationRunning = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
if (thumbnailData != null) {
|
||||
mOverviewComponentObserver.getActivityControlHelper().switchToScreenshot(thumbnailData,
|
||||
() -> {
|
||||
mLastRecentsAnimationController.cleanupScreenshot();
|
||||
clearAnimationState();
|
||||
});
|
||||
} else {
|
||||
clearAnimationState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRecentsAnimationFinished(RecentsAnimationWrapper controller) {
|
||||
if (mLastRecentsAnimationController == controller) {
|
||||
mLastAnimationRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearAnimationTarget() {
|
||||
if (mLastAnimationTarget != null) {
|
||||
mLastAnimationTarget.release();
|
||||
@@ -71,42 +91,23 @@ public class SwipeSharedState implements RecentsAnimationListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
if (thumbnailData != null) {
|
||||
mOverviewComponentObserver.getActivityControlHelper().switchToScreenshot(thumbnailData,
|
||||
() -> {
|
||||
if (mRecentsAnimationCanceledCallback != null) {
|
||||
mRecentsAnimationCanceledCallback.run();
|
||||
}
|
||||
clearAnimationState();
|
||||
});
|
||||
} else {
|
||||
clearAnimationState();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRecentsAnimationCanceledCallback(Runnable callback) {
|
||||
mRecentsAnimationCanceledCallback = callback;
|
||||
}
|
||||
|
||||
private void clearAnimationState() {
|
||||
clearAnimationTarget();
|
||||
|
||||
mLastAnimationCancelled = true;
|
||||
mLastAnimationRunning = false;
|
||||
mRecentsAnimationCanceledCallback = null;
|
||||
}
|
||||
|
||||
private void clearListenerState(boolean finishAnimation) {
|
||||
if (mRecentsAnimationListener != null) {
|
||||
mRecentsAnimationListener.removeListener(this);
|
||||
mRecentsAnimationListener.cancelListener();
|
||||
if (mLastAnimationRunning && mLastAnimationTarget != null) {
|
||||
mRecentsAnimationListener.notifyAnimationCanceled();
|
||||
if (mLastAnimationRunning && mLastRecentsAnimationController != null) {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
|
||||
finishAnimation
|
||||
? mLastAnimationTarget::finishAnimation
|
||||
: mLastAnimationTarget::cancelAnimation);
|
||||
? mLastRecentsAnimationController::finishAnimationToHome
|
||||
: mLastRecentsAnimationController::finishAnimationToApp);
|
||||
mLastRecentsAnimationController = null;
|
||||
mLastAnimationTarget = null;
|
||||
}
|
||||
}
|
||||
@@ -116,12 +117,6 @@ public class SwipeSharedState implements RecentsAnimationListener {
|
||||
mLastAnimationRunning = false;
|
||||
}
|
||||
|
||||
private void onSwipeAnimationFinished(RecentsAnimationTargets targetSet) {
|
||||
if (mLastAnimationTarget == targetSet) {
|
||||
mLastAnimationRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
public RecentsAnimationCallbacks newRecentsAnimationListenerSet() {
|
||||
Preconditions.assertUIThread();
|
||||
|
||||
@@ -137,8 +132,7 @@ public class SwipeSharedState implements RecentsAnimationListener {
|
||||
clearListenerState(false /* finishAnimation */);
|
||||
boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false
|
||||
: mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen();
|
||||
mRecentsAnimationListener = new RecentsAnimationCallbacks(
|
||||
shouldMinimiseSplitScreen, this::onSwipeAnimationFinished);
|
||||
mRecentsAnimationListener = new RecentsAnimationCallbacks(shouldMinimiseSplitScreen);
|
||||
mRecentsAnimationListener.addListener(this);
|
||||
return mRecentsAnimationListener;
|
||||
}
|
||||
@@ -148,8 +142,9 @@ public class SwipeSharedState implements RecentsAnimationListener {
|
||||
}
|
||||
|
||||
public void applyActiveRecentsAnimationState(RecentsAnimationListener listener) {
|
||||
if (mLastAnimationTarget != null) {
|
||||
listener.onRecentsAnimationStart(mLastAnimationTarget);
|
||||
if (mLastRecentsAnimationController != null) {
|
||||
listener.onRecentsAnimationStart(mLastRecentsAnimationController,
|
||||
mLastAnimationTarget);
|
||||
} else if (mLastAnimationCancelled) {
|
||||
listener.onRecentsAnimationCanceled(null);
|
||||
}
|
||||
|
||||
+3
-4
@@ -414,10 +414,9 @@ public class TouchInteractionService extends Service implements
|
||||
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we should
|
||||
// not interrupt it. QuickSwitch assumes that interruption can only happen if the
|
||||
// next gesture is also quick switch.
|
||||
mUncheckedConsumer =
|
||||
new AssistantInputConsumer(this,
|
||||
mOverviewComponentObserver.getActivityControlHelper(),
|
||||
InputConsumer.NO_OP, mInputMonitorCompat);
|
||||
mUncheckedConsumer = new AssistantInputConsumer(this,
|
||||
mOverviewComponentObserver.getActivityControlHelper(),
|
||||
InputConsumer.NO_OP, mInputMonitorCompat);
|
||||
} else {
|
||||
mUncheckedConsumer = InputConsumer.NO_OP;
|
||||
}
|
||||
|
||||
+33
-28
@@ -291,9 +291,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
mStateCallback.addCallback(STATE_HANDLER_INVALIDATED | STATE_RESUME_LAST_TASK,
|
||||
this::notifyTransitionCancelled);
|
||||
|
||||
mStateCallback.addCallback(STATE_APP_CONTROLLER_RECEIVED | STATE_GESTURE_STARTED,
|
||||
mRecentsAnimationWrapper::enableInputConsumer);
|
||||
|
||||
if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
mStateCallback.addChangeHandler(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT
|
||||
| STATE_SCREENSHOT_VIEW_SHOWN | STATE_CAPTURE_SCREENSHOT,
|
||||
@@ -417,7 +414,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
|
||||
private void sendRemoteAnimationsToAnimationFactory() {
|
||||
mAnimationFactory.onRemoteAnimationReceived(mRecentsAnimationWrapper.targetSet);
|
||||
mAnimationFactory.onRemoteAnimationReceived(mRecentsAnimationTargets);
|
||||
}
|
||||
|
||||
private void initializeLauncherAnimationController() {
|
||||
@@ -464,9 +461,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
if (mMode != Mode.NO_BUTTON || mRecentsView == null) {
|
||||
return;
|
||||
}
|
||||
RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationWrapper.targetSet == null
|
||||
RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationTargets == null
|
||||
? null
|
||||
: mRecentsAnimationWrapper.targetSet.findTask(mRunningTaskId);
|
||||
: mRecentsAnimationTargets.findTask(mRunningTaskId);
|
||||
final boolean recentsAttachedToAppWindow;
|
||||
int runningTaskIndex = mRecentsView.getRunningTaskIndex();
|
||||
if (mGestureEndTarget != null) {
|
||||
@@ -548,15 +545,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
|
||||
RecentsAnimationTargets controller = mRecentsAnimationWrapper.getController();
|
||||
if (controller != null) {
|
||||
if (mRecentsAnimationTargets != null) {
|
||||
applyTransformUnchecked();
|
||||
updateSysUiFlags(mCurrentShift.value);
|
||||
}
|
||||
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
if (mRecentsAnimationWrapper.getController() != null) {
|
||||
if (mRecentsAnimationTargets != null) {
|
||||
mLiveTileOverlay.update(mAppWindowAnimationHelper.getCurrentRectWithInsets(),
|
||||
mAppWindowAnimationHelper.getCurrentCornerRadius());
|
||||
}
|
||||
@@ -599,17 +594,24 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
: centermostTask.getThumbnail().getSysUiStatusNavFlags();
|
||||
boolean useHomeScreenFlags = windowProgress > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||
// We will handle the sysui flags based on the centermost task view.
|
||||
mRecentsAnimationWrapper.setWindowThresholdCrossed(centermostTaskFlags != 0
|
||||
|| useHomeScreenFlags);
|
||||
if (mRecentsAnimationWrapper != null) {
|
||||
mRecentsAnimationWrapper.setWindowThresholdCrossed(centermostTaskFlags != 0
|
||||
|| useHomeScreenFlags);
|
||||
}
|
||||
int sysuiFlags = useHomeScreenFlags ? 0 : centermostTaskFlags;
|
||||
mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
|
||||
super.onRecentsAnimationStart(targetSet);
|
||||
public void onRecentsAnimationStart(RecentsAnimationWrapper controller,
|
||||
RecentsAnimationTargets targetSet) {
|
||||
ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targetSet.apps.length);
|
||||
super.onRecentsAnimationStart(controller, targetSet);
|
||||
|
||||
// Only add the callback to enable the input consumer after we actually have the controller
|
||||
mStateCallback.addCallback(STATE_APP_CONTROLLER_RECEIVED | STATE_GESTURE_STARTED,
|
||||
mRecentsAnimationWrapper::enableInputConsumer);
|
||||
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
|
||||
|
||||
mPassedOverviewThreshold = false;
|
||||
@@ -617,7 +619,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
mRecentsAnimationWrapper.setController(null);
|
||||
super.onRecentsAnimationCanceled(thumbnailData);
|
||||
mRecentsView.setRecentsAnimationTargets(null, null);
|
||||
mActivityInitListener.unregister();
|
||||
setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
|
||||
ActiveGestureLog.INSTANCE.addLog("cancelRecentsAnimation");
|
||||
@@ -707,7 +710,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
final GestureEndTarget endTarget;
|
||||
final boolean goingToNewTask;
|
||||
if (mRecentsView != null) {
|
||||
if (!mRecentsAnimationWrapper.hasTargets()) {
|
||||
if (!hasTargets()) {
|
||||
// If there are no running tasks, then we can assume that this is a continuation of
|
||||
// the last gesture, but after the recents animation has finished
|
||||
goingToNewTask = true;
|
||||
@@ -810,8 +813,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
}
|
||||
|
||||
if (endTarget.isLauncher) {
|
||||
mRecentsAnimationWrapper.enableInputProxy();
|
||||
if (endTarget.isLauncher && mRecentsAnimationWrapper != null) {
|
||||
mRecentsAnimationWrapper.enableInputProxy(mInputConsumer,
|
||||
this::createNewInputProxyHandler);
|
||||
}
|
||||
|
||||
if (endTarget == HOME) {
|
||||
@@ -866,7 +870,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
@UiThread
|
||||
private void animateToProgress(float start, float end, long duration, Interpolator interpolator,
|
||||
GestureEndTarget target, PointF velocityPxPerMs) {
|
||||
mRecentsAnimationWrapper.runOnInit(() -> animateToProgressInternal(start, end, duration,
|
||||
runOnRecentsAnimationStart(() -> animateToProgressInternal(start, end, duration,
|
||||
interpolator, target, velocityPxPerMs));
|
||||
}
|
||||
|
||||
@@ -1108,25 +1112,24 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
|
||||
private void switchToScreenshot() {
|
||||
RecentsAnimationTargets controller = mRecentsAnimationWrapper.getController();
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
if (controller != null) {
|
||||
if (mRecentsAnimationWrapper != null) {
|
||||
// Update the screenshot of the task
|
||||
if (mTaskSnapshot == null) {
|
||||
mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
|
||||
mTaskSnapshot = mRecentsAnimationWrapper.screenshotTask(mRunningTaskId);
|
||||
}
|
||||
mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot, false /* refreshNow */);
|
||||
}
|
||||
setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
|
||||
} else if (!mRecentsAnimationWrapper.hasTargets()) {
|
||||
} else if (!hasTargets()) {
|
||||
// If there are no targets, then we don't need to capture anything
|
||||
setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
|
||||
} else {
|
||||
boolean finishTransitionPosted = false;
|
||||
if (controller != null) {
|
||||
if (mRecentsAnimationWrapper != null) {
|
||||
// Update the screenshot of the task
|
||||
if (mTaskSnapshot == null) {
|
||||
mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
|
||||
mTaskSnapshot = mRecentsAnimationWrapper.screenshotTask(mRunningTaskId);
|
||||
}
|
||||
final TaskView taskView;
|
||||
if (mGestureEndTarget == HOME) {
|
||||
@@ -1155,7 +1158,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
private void finishCurrentTransitionToRecents() {
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
|
||||
} else if (!mRecentsAnimationWrapper.hasTargets()) {
|
||||
} else if (!hasTargets()) {
|
||||
// If there are no targets, then there is nothing to finish
|
||||
setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
|
||||
} else {
|
||||
@@ -1180,8 +1183,10 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
private void setupLauncherUiAfterSwipeUpToRecentsAnimation() {
|
||||
endLauncherTransitionController();
|
||||
mActivityControlHelper.onSwipeUpToRecentsComplete(mActivity);
|
||||
mRecentsAnimationWrapper.setDeferCancelUntilNextTransition(true /* defer */,
|
||||
true /* screenshot */);
|
||||
if (mRecentsAnimationWrapper != null) {
|
||||
mRecentsAnimationWrapper.setDeferCancelUntilNextTransition(true /* defer */,
|
||||
true /* screenshot */);
|
||||
}
|
||||
mRecentsView.onSwipeUpAnimationSuccess();
|
||||
|
||||
RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG);
|
||||
|
||||
+12
-7
@@ -42,6 +42,7 @@ import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.quickstep.LockScreenRecentsActivity;
|
||||
import com.android.quickstep.MultiStateCallback;
|
||||
import com.android.quickstep.RecentsAnimationDeviceState;
|
||||
import com.android.quickstep.RecentsAnimationWrapper;
|
||||
import com.android.quickstep.SwipeSharedState;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||
import com.android.quickstep.util.RecentsAnimationCallbacks;
|
||||
@@ -91,7 +92,8 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
|
||||
private boolean mThresholdCrossed = false;
|
||||
|
||||
private RecentsAnimationTargets mTargetSet;
|
||||
private RecentsAnimationWrapper mRecentsAnimationController;
|
||||
private RecentsAnimationTargets mRecentsAnimationTargets;
|
||||
|
||||
public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
|
||||
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
|
||||
@@ -216,8 +218,10 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
|
||||
mTargetSet = targetSet;
|
||||
public void onRecentsAnimationStart(RecentsAnimationWrapper controller,
|
||||
RecentsAnimationTargets targetSet) {
|
||||
mRecentsAnimationController = controller;
|
||||
mRecentsAnimationTargets = targetSet;
|
||||
|
||||
Rect displaySize = new Rect(0, 0, mDisplaySize.x, mDisplaySize.y);
|
||||
RemoteAnimationTargetCompat targetCompat = targetSet.findTask(mRunningTaskId);
|
||||
@@ -227,7 +231,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
|
||||
Utilities.scaleRectAboutCenter(displaySize, SCALE_DOWN);
|
||||
displaySize.offsetTo(displaySize.left, 0);
|
||||
mTransformParams.setTargetSet(mTargetSet)
|
||||
mTransformParams.setTargetSet(mRecentsAnimationTargets)
|
||||
.setLauncherOnTop(true);
|
||||
mAppWindowAnimationHelper.updateTargetRect(displaySize);
|
||||
mAppWindowAnimationHelper.applyTransform(mTransformParams);
|
||||
@@ -237,12 +241,13 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
mTargetSet = null;
|
||||
mRecentsAnimationController = null;
|
||||
mRecentsAnimationTargets = null;
|
||||
}
|
||||
|
||||
private void endRemoteAnimation() {
|
||||
if (mTargetSet != null) {
|
||||
mTargetSet.finishController(
|
||||
if (mRecentsAnimationController != null) {
|
||||
mRecentsAnimationController.finishController(
|
||||
false /* toRecents */, null /* callback */, false /* sendUserLeaveHint */);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-11
@@ -45,6 +45,7 @@ import com.android.quickstep.BaseSwipeUpHandler;
|
||||
import com.android.quickstep.MultiStateCallback;
|
||||
import com.android.quickstep.OverviewComponentObserver;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.RecentsAnimationWrapper;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.SwipeSharedState;
|
||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||
@@ -157,7 +158,7 @@ public class FallbackNoButtonInputConsumer extends
|
||||
}
|
||||
|
||||
private void onLauncherAlphaChanged() {
|
||||
if (mRecentsAnimationWrapper.targetSet != null && mEndTarget == null) {
|
||||
if (mRecentsAnimationTargets != null && mEndTarget == null) {
|
||||
applyTransformUnchecked();
|
||||
}
|
||||
}
|
||||
@@ -231,9 +232,11 @@ public class FallbackNoButtonInputConsumer extends
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
mTransformParams.setProgress(mCurrentShift.value);
|
||||
mRecentsAnimationWrapper.setWindowThresholdCrossed(!mInQuickSwitchMode
|
||||
&& (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD));
|
||||
if (mRecentsAnimationWrapper.targetSet != null) {
|
||||
if (mRecentsAnimationWrapper != null) {
|
||||
mRecentsAnimationWrapper.setWindowThresholdCrossed(!mInQuickSwitchMode
|
||||
&& (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD));
|
||||
}
|
||||
if (mRecentsAnimationTargets != null) {
|
||||
applyTransformUnchecked();
|
||||
}
|
||||
}
|
||||
@@ -333,8 +336,7 @@ public class FallbackNoButtonInputConsumer extends
|
||||
break;
|
||||
}
|
||||
|
||||
ThumbnailData thumbnail =
|
||||
mRecentsAnimationWrapper.targetSet.controller.screenshotTask(mRunningTaskId);
|
||||
ThumbnailData thumbnail = mRecentsAnimationWrapper.screenshotTask(mRunningTaskId);
|
||||
mRecentsAnimationWrapper.setDeferCancelUntilNextTransition(true /* defer */,
|
||||
false /* screenshot */);
|
||||
|
||||
@@ -348,7 +350,7 @@ public class FallbackNoButtonInputConsumer extends
|
||||
Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent())
|
||||
.putExtras(extras);
|
||||
mContext.startActivity(intent, options.toBundle());
|
||||
mRecentsAnimationWrapper.targetSet.controller.cleanupScreenshot();
|
||||
mRecentsAnimationWrapper.cleanupScreenshot();
|
||||
break;
|
||||
}
|
||||
case NEW_TASK: {
|
||||
@@ -364,7 +366,7 @@ public class FallbackNoButtonInputConsumer extends
|
||||
if (mInQuickSwitchMode) {
|
||||
// Recalculate the end target, some views might have been initialized after
|
||||
// gesture has ended.
|
||||
if (mRecentsView == null || !mRecentsAnimationWrapper.hasTargets()) {
|
||||
if (mRecentsView == null || !hasTargets()) {
|
||||
mEndTarget = LAST_TASK;
|
||||
} else {
|
||||
final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
|
||||
@@ -414,8 +416,9 @@ public class FallbackNoButtonInputConsumer extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
|
||||
super.onRecentsAnimationStart(targetSet);
|
||||
public void onRecentsAnimationStart(RecentsAnimationWrapper controller,
|
||||
RecentsAnimationTargets targetSet) {
|
||||
super.onRecentsAnimationStart(controller, targetSet);
|
||||
mRecentsAnimationWrapper.enableInputConsumer();
|
||||
|
||||
if (mRunningOverHome) {
|
||||
@@ -428,7 +431,7 @@ public class FallbackNoButtonInputConsumer extends
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
mRecentsAnimationWrapper.setController(null);
|
||||
mRecentsView.setRecentsAnimationTargets(null, null);
|
||||
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
}
|
||||
|
||||
|
||||
+46
-37
@@ -26,33 +26,30 @@ import androidx.annotation.UiThread;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.quickstep.TouchInteractionService;
|
||||
import com.android.quickstep.RecentsAnimationWrapper;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Wrapper around {@link com.android.systemui.shared.system.RecentsAnimationListener} which delegates callbacks to multiple listeners
|
||||
* on the main thread
|
||||
* Wrapper around {@link com.android.systemui.shared.system.RecentsAnimationListener} which
|
||||
* delegates callbacks to multiple listeners on the main thread
|
||||
*/
|
||||
public class RecentsAnimationCallbacks implements
|
||||
com.android.systemui.shared.system.RecentsAnimationListener {
|
||||
|
||||
private final Set<RecentsAnimationListener> mListeners = new ArraySet<>();
|
||||
private final boolean mShouldMinimizeSplitScreen;
|
||||
private final Consumer<RecentsAnimationTargets> mOnFinishListener;
|
||||
private RecentsAnimationControllerCompat mController;
|
||||
|
||||
// TODO(141886704): Remove these references when they are no longer needed
|
||||
private RecentsAnimationWrapper mController;
|
||||
|
||||
private boolean mCancelled;
|
||||
|
||||
public RecentsAnimationCallbacks(boolean shouldMinimizeSplitScreen,
|
||||
Consumer<RecentsAnimationTargets> onFinishListener) {
|
||||
public RecentsAnimationCallbacks(boolean shouldMinimizeSplitScreen) {
|
||||
mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen;
|
||||
mOnFinishListener = onFinishListener;
|
||||
TouchInteractionService.getSwipeSharedState().setRecentsAnimationCanceledCallback(
|
||||
() -> mController.cleanupScreenshot());
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -67,26 +64,9 @@ public class RecentsAnimationCallbacks implements
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
// Called only in R+ platform
|
||||
@BinderThread
|
||||
public final void onAnimationStart(RecentsAnimationControllerCompat controller,
|
||||
RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
Rect homeContentInsets, Rect minimizedHomeBounds) {
|
||||
mController = controller;
|
||||
RecentsAnimationTargets targetSet = new RecentsAnimationTargets(controller, appTargets,
|
||||
wallpaperTargets, homeContentInsets, minimizedHomeBounds,
|
||||
mShouldMinimizeSplitScreen, mOnFinishListener);
|
||||
|
||||
if (mCancelled) {
|
||||
targetSet.cancelAnimation();
|
||||
} else {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
|
||||
for (RecentsAnimationListener listener : getListeners()) {
|
||||
listener.onRecentsAnimationStart(targetSet);
|
||||
}
|
||||
});
|
||||
}
|
||||
public void notifyAnimationCanceled() {
|
||||
mCancelled = true;
|
||||
onAnimationCanceled(null);
|
||||
}
|
||||
|
||||
// Called only in Q platform
|
||||
@@ -99,6 +79,29 @@ public class RecentsAnimationCallbacks implements
|
||||
homeContentInsets, minimizedHomeBounds);
|
||||
}
|
||||
|
||||
// Called only in R+ platform
|
||||
@BinderThread
|
||||
public final void onAnimationStart(RecentsAnimationControllerCompat animationController,
|
||||
RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
Rect homeContentInsets, Rect minimizedHomeBounds) {
|
||||
RecentsAnimationTargets targetSet = new RecentsAnimationTargets(appTargets,
|
||||
wallpaperTargets, homeContentInsets, minimizedHomeBounds);
|
||||
mController = new RecentsAnimationWrapper(animationController, mShouldMinimizeSplitScreen,
|
||||
this::onAnimationFinished);
|
||||
|
||||
if (mCancelled) {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
|
||||
mController::finishAnimationToApp);
|
||||
} else {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
|
||||
for (RecentsAnimationListener listener : getListeners()) {
|
||||
listener.onRecentsAnimationStart(mController, targetSet);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public final void onAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
@@ -109,25 +112,31 @@ public class RecentsAnimationCallbacks implements
|
||||
});
|
||||
}
|
||||
|
||||
private RecentsAnimationListener[] getListeners() {
|
||||
return mListeners.toArray(new RecentsAnimationListener[mListeners.size()]);
|
||||
private final void onAnimationFinished(RecentsAnimationWrapper controller) {
|
||||
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
|
||||
for (RecentsAnimationListener listener : getListeners()) {
|
||||
listener.onRecentsAnimationFinished(controller);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void cancelListener() {
|
||||
mCancelled = true;
|
||||
onAnimationCanceled(null);
|
||||
private RecentsAnimationListener[] getListeners() {
|
||||
return mListeners.toArray(new RecentsAnimationListener[mListeners.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for the recents animation callbacks.
|
||||
*/
|
||||
public interface RecentsAnimationListener {
|
||||
void onRecentsAnimationStart(RecentsAnimationTargets targetSet);
|
||||
default void onRecentsAnimationStart(RecentsAnimationWrapper controller,
|
||||
RecentsAnimationTargets targetSet) {}
|
||||
|
||||
/**
|
||||
* Callback from the system when the recents animation is canceled. {@param thumbnailData}
|
||||
* is passed back for rendering screenshot to replace live tile.
|
||||
*/
|
||||
void onRecentsAnimationCanceled(ThumbnailData thumbnailData);
|
||||
default void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {}
|
||||
|
||||
default void onRecentsAnimationFinished(RecentsAnimationWrapper controller) {}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-64
@@ -15,41 +15,27 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Extension of {@link RemoteAnimationTargets} with additional information about swipe
|
||||
* up animation
|
||||
*/
|
||||
public class RecentsAnimationTargets extends RemoteAnimationTargets {
|
||||
|
||||
private final boolean mShouldMinimizeSplitScreen;
|
||||
private final Consumer<RecentsAnimationTargets> mOnFinishListener;
|
||||
|
||||
public final RecentsAnimationControllerCompat controller;
|
||||
public final Rect homeContentInsets;
|
||||
public final Rect minimizedHomeBounds;
|
||||
|
||||
public RecentsAnimationTargets(RecentsAnimationControllerCompat controller,
|
||||
RemoteAnimationTargetCompat[] apps, RemoteAnimationTargetCompat[] wallpapers,
|
||||
Rect homeContentInsets, Rect minimizedHomeBounds, boolean shouldMinimizeSplitScreen,
|
||||
Consumer<RecentsAnimationTargets> onFinishListener) {
|
||||
public RecentsAnimationTargets(RemoteAnimationTargetCompat[] apps,
|
||||
RemoteAnimationTargetCompat[] wallpapers, Rect homeContentInsets,
|
||||
Rect minimizedHomeBounds) {
|
||||
super(apps, wallpapers, MODE_CLOSING);
|
||||
this.controller = controller;
|
||||
this.homeContentInsets = homeContentInsets;
|
||||
this.minimizedHomeBounds = minimizedHomeBounds;
|
||||
this.mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen;
|
||||
this.mOnFinishListener = onFinishListener;
|
||||
}
|
||||
|
||||
public boolean hasTargets() {
|
||||
@@ -61,52 +47,7 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
|
||||
* the actual recents animation has finished.
|
||||
*/
|
||||
public RecentsAnimationTargets cloneWithoutTargets() {
|
||||
return new RecentsAnimationTargets(controller, new RemoteAnimationTargetCompat[0],
|
||||
new RemoteAnimationTargetCompat[0], homeContentInsets, minimizedHomeBounds,
|
||||
mShouldMinimizeSplitScreen, mOnFinishListener);
|
||||
}
|
||||
|
||||
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
|
||||
mOnFinishListener.accept(this);
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
controller.setInputConsumerEnabled(false);
|
||||
controller.finish(toRecents, sendUserLeaveHint);
|
||||
|
||||
if (callback != null) {
|
||||
MAIN_EXECUTOR.execute(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void enableInputConsumer() {
|
||||
UI_HELPER_EXECUTOR.submit(() -> {
|
||||
controller.hideCurrentInputMethod();
|
||||
controller.setInputConsumerEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void setWindowThresholdCrossed(boolean thresholdCrossed) {
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
controller.setAnimationTargetsBehindSystemBars(!thresholdCrossed);
|
||||
if (mShouldMinimizeSplitScreen && thresholdCrossed) {
|
||||
// NOTE: As a workaround for conflicting animations (Launcher animating the task
|
||||
// leash, and SystemUI resizing the docked stack, which resizes the task), we
|
||||
// currently only set the minimized mode, and not the inverse.
|
||||
// TODO: Synchronize the minimize animation with the launcher animation
|
||||
controller.setSplitScreenMinimized(thresholdCrossed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ThumbnailData screenshotTask(int taskId) {
|
||||
return controller != null ? controller.screenshotTask(taskId) : null;
|
||||
}
|
||||
|
||||
public void cancelAnimation() {
|
||||
finishController(false /* toRecents */, null, false /* sendUserLeaveHint */);
|
||||
}
|
||||
|
||||
public void finishAnimation() {
|
||||
finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
|
||||
return new RecentsAnimationTargets(new RemoteAnimationTargetCompat[0],
|
||||
new RemoteAnimationTargetCompat[0], homeContentInsets, minimizedHomeBounds);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -221,7 +221,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements StateL
|
||||
public AppWindowAnimationHelper.TransformParams getLiveTileParams(
|
||||
boolean mightNeedToRefill) {
|
||||
if (!mEnableDrawingLiveTile || mRecentsAnimationWrapper == null
|
||||
|| mAppWindowAnimationHelper == null) {
|
||||
|| mRecentsAnimationTargets == null || mAppWindowAnimationHelper == null) {
|
||||
return null;
|
||||
}
|
||||
TaskView taskView = getRunningTaskView();
|
||||
@@ -245,7 +245,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements StateL
|
||||
mTransformParams.setProgress(1f)
|
||||
.setCurrentRectAndTargetAlpha(mTempRectF, taskView.getAlpha())
|
||||
.setSyncTransactionApplier(mSyncTransactionApplier)
|
||||
.setTargetSet(mRecentsAnimationWrapper.targetSet)
|
||||
.setTargetSet(mRecentsAnimationTargets)
|
||||
.setLauncherOnTop(true);
|
||||
}
|
||||
return mTransformParams;
|
||||
|
||||
@@ -108,6 +108,7 @@ import com.android.quickstep.TaskThumbnailCache;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.ViewUtils;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||
import com.android.quickstep.util.RecentsAnimationTargets;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -156,6 +157,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
};
|
||||
|
||||
protected RecentsAnimationWrapper mRecentsAnimationWrapper;
|
||||
protected RecentsAnimationTargets mRecentsAnimationTargets;
|
||||
protected AppWindowAnimationHelper mAppWindowAnimationHelper;
|
||||
protected SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
|
||||
protected int mTaskWidth;
|
||||
@@ -808,6 +810,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
mTaskListChangeId = -1;
|
||||
|
||||
mRecentsAnimationWrapper = null;
|
||||
mRecentsAnimationTargets = null;
|
||||
mAppWindowAnimationHelper = null;
|
||||
|
||||
unloadVisibleTaskData();
|
||||
@@ -1692,10 +1695,14 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
public void redrawLiveTile(boolean mightNeedToRefill) { }
|
||||
|
||||
public void setRecentsAnimationWrapper(RecentsAnimationWrapper recentsAnimationWrapper) {
|
||||
// TODO: To be removed in a follow up CL
|
||||
public void setRecentsAnimationTargets(RecentsAnimationWrapper recentsAnimationWrapper,
|
||||
RecentsAnimationTargets recentsAnimationTargets) {
|
||||
mRecentsAnimationWrapper = recentsAnimationWrapper;
|
||||
mRecentsAnimationTargets = recentsAnimationTargets;
|
||||
}
|
||||
|
||||
// TODO: To be removed in a follow up CL
|
||||
public void setAppWindowAnimationHelper(AppWindowAnimationHelper appWindowAnimationHelper) {
|
||||
mAppWindowAnimationHelper = appWindowAnimationHelper;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@ public class RemoteAnimationTargets {
|
||||
for (RemoteAnimationTargetCompat target : unfilteredApps) {
|
||||
target.release();
|
||||
}
|
||||
for (RemoteAnimationTargetCompat target : wallpapers) {
|
||||
target.release();
|
||||
}
|
||||
} else {
|
||||
applier.addAfterApplyCallback(this::release);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user