blob: 8783ee3cc70a8eb27e2da79f38d31d264851769c [file] [log] [blame]
/*
* 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 static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.util.Log;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
import java.io.PrintWriter;
/**
* Utility class used to store state information shared across multiple transitions.
*/
public class SwipeSharedState implements SwipeAnimationListener {
private OverviewComponentObserver mOverviewComponentObserver;
private RecentsAnimationListenerSet mRecentsAnimationListener;
private SwipeAnimationTargetSet mLastAnimationTarget;
private boolean mLastAnimationCancelled = false;
private boolean mLastAnimationRunning = false;
public boolean canGestureBeContinued;
public boolean goingToLauncher;
public boolean recentsAnimationFinishInterrupted;
public int nextRunningTaskId = -1;
private int mLogId;
public void setOverviewComponentObserver(OverviewComponentObserver observer) {
mOverviewComponentObserver = observer;
}
@Override
public final void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
mLastAnimationTarget = targetSet;
mLastAnimationCancelled = false;
mLastAnimationRunning = true;
}
private void clearAnimationTarget() {
if (mLastAnimationTarget != null) {
mLastAnimationTarget.release();
mLastAnimationTarget = null;
}
}
@Override
public final void onRecentsAnimationCanceled() {
clearAnimationTarget();
mLastAnimationCancelled = true;
mLastAnimationRunning = false;
}
private void clearListenerState(boolean finishAnimation) {
if (mRecentsAnimationListener != null) {
mRecentsAnimationListener.removeListener(this);
mRecentsAnimationListener.cancelListener();
if (mLastAnimationRunning && mLastAnimationTarget != null) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
finishAnimation
? mLastAnimationTarget::finishAnimation
: mLastAnimationTarget::cancelAnimation);
mLastAnimationTarget = null;
}
}
mRecentsAnimationListener = null;
clearAnimationTarget();
mLastAnimationCancelled = false;
mLastAnimationRunning = false;
}
private void onSwipeAnimationFinished(SwipeAnimationTargetSet targetSet) {
if (mLastAnimationTarget == targetSet) {
mLastAnimationRunning = false;
}
}
public RecentsAnimationListenerSet newRecentsAnimationListenerSet() {
Preconditions.assertUIThread();
if (mLastAnimationRunning) {
String msg = "New animation started before completing old animation";
if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new IllegalArgumentException(msg);
} else {
Log.e("SwipeSharedState", msg, new Exception());
}
}
clearListenerState(false /* finishAnimation */);
boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false
: mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen();
mRecentsAnimationListener = new RecentsAnimationListenerSet(
shouldMinimiseSplitScreen, this::onSwipeAnimationFinished);
mRecentsAnimationListener.addListener(this);
return mRecentsAnimationListener;
}
public RecentsAnimationListenerSet getActiveListener() {
return mRecentsAnimationListener;
}
public void applyActiveRecentsAnimationState(SwipeAnimationListener listener) {
if (mLastAnimationTarget != null) {
listener.onRecentsAnimationStart(mLastAnimationTarget);
} else if (mLastAnimationCancelled) {
listener.onRecentsAnimationCanceled();
}
}
/**
* 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;
mLastAnimationTarget = mLastAnimationTarget.cloneWithoutTargets();
}
public void clearAllState(boolean finishAnimation) {
clearListenerState(finishAnimation);
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 + "lastAnimationCancelled=" + mLastAnimationCancelled);
pw.println(prefix + "lastAnimationRunning=" + mLastAnimationRunning);
pw.println(prefix + "logTraceId=" + mLogId);
}
public void setLogTraceId(int logId) {
this.mLogId = logId;
}
}