Trigger onTaskAppeared when a task started from recents becomes ready.

Launcher can now receive onTaskAppeared callback from
RecentsAnimationController to get remote animation target when in quick
switch mode.

Note: This CL just demonstrates how to receive callback and then
calling removeTask & finish recents animation,
in order to really improve quick switch flicking, launcher side needs
to implement the rest of logic to animate task's remote animation target
to make task switching more smoothly.

Bug: 152480470
Test: WIP
Change-Id: Id0371db7339cfe84942cc905a89b0a2c1fab62ec
This commit is contained in:
lumark
2020-03-07 00:09:21 +08:00
committed by Ming-Shin Lu
parent f24c614ad2
commit bec41bc5b9
5 changed files with 80 additions and 29 deletions

View File

@@ -212,36 +212,23 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
Log.d(TestProtocol.NO_START_FROM_RECENTS, "startNewTask2");
}
int taskId = mRecentsView.getNextPageTaskView().getTask().key.id;
mFinishingRecentsAnimationForNewTaskId = taskId;
mRecentsAnimationController.finish(true /* toRecents */, () -> {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_START_FROM_RECENTS, "onFinishComplete1");
if (!mCanceled) {
TaskView nextTask = mRecentsView.getTaskView(taskId);
if (nextTask != null) {
nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
success -> {
resultCallback.accept(success);
if (!success) {
mActivityInterface.onLaunchTaskFailed();
nextTask.notifyTaskLaunchFailed(TAG);
} else {
mActivityInterface.onLaunchTaskSuccess();
}
}, MAIN_EXECUTOR.getHandler());
}
if (!mCanceled) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_START_FROM_RECENTS, "onFinishComplete2");
}
TaskView nextTask = mRecentsView.getTaskView(taskId);
if (nextTask != null) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_START_FROM_RECENTS, "onFinishComplete3");
}
nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
success -> {
resultCallback.accept(success);
if (!success) {
mActivityInterface.onLaunchTaskFailed();
nextTask.notifyTaskLaunchFailed(TAG);
} else {
mActivityInterface.onLaunchTaskSuccess();
}
}, MAIN_EXECUTOR.getHandler());
}
mStateCallback.setStateOnUiThread(successStateFlag);
}
mCanceled = false;
mFinishingRecentsAnimationForNewTaskId = -1;
});
mStateCallback.setStateOnUiThread(successStateFlag);
}
mCanceled = false;
}
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
}

View File

@@ -30,6 +30,7 @@ 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.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
import static com.android.quickstep.GestureState.STATE_TASK_APPEARED_DURING_SWITCH;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
@@ -253,6 +254,8 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
| STATE_RECENTS_SCROLLING_FINISHED,
this::onSettledOnEndTarget);
mGestureState.runOnceAtState(STATE_TASK_APPEARED_DURING_SWITCH, this::onTaskAppeared);
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher);
@@ -727,6 +730,22 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
}
}
private void onTaskAppeared() {
RemoteAnimationTargetCompat app = mGestureState.getAnimationTarget();
if (mRecentsAnimationController != null && app != null) {
// TODO(b/152480470): Update Task target animation after onTaskAppeared holistically.
/* android.util.Log.d("LauncherSwipeHandler", "onTaskAppeared");
final boolean result = mRecentsAnimationController.removeTaskTarget(app);
mGestureState.setAnimationTarget(null);
android.util.Log.d("LauncherSwipeHandler", "removeTask, result=" + result); */
mRecentsAnimationController.finish(false /* toRecents */,
null /* onFinishComplete */);
}
}
private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
boolean isCancel) {
final GestureEndTarget endTarget;

View File

@@ -23,6 +23,7 @@ import android.content.Intent;
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.system.RemoteAnimationTargetCompat;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -109,6 +110,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
public static final int STATE_RECENTS_SCROLLING_FINISHED =
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
// Called when the new task appeared from quick switching.
public static final int STATE_TASK_APPEARED_DURING_SWITCH =
getFlagForIndex("STATE_TASK_APPEARED_DURING_SWITCH");
// Needed to interact with the current activity
private final Intent mHomeIntent;
@@ -119,6 +123,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
private ActivityManager.RunningTaskInfo mRunningTask;
private GestureEndTarget mEndTarget;
private RemoteAnimationTargetCompat mAnimationTarget;
// TODO: This can be removed once we stop finishing the animation when starting a new task
private int mFinishingRecentsAnimationTaskId = -1;
@@ -227,6 +232,14 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
return mEndTarget;
}
public void setAnimationTarget(RemoteAnimationTargetCompat target) {
mAnimationTarget = target;
}
public RemoteAnimationTargetCompat getAnimationTarget() {
return mAnimationTarget;
}
/**
* Sets the end target of this gesture and immediately notifies the state changes.
*/
@@ -301,6 +314,12 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
}
@Override
public void onTaskAppeared(RemoteAnimationTargetCompat app) {
mAnimationTarget = app;
mStateCallback.setState(STATE_TASK_APPEARED_DURING_SWITCH);
}
public void dump(PrintWriter pw) {
pw.println("GestureState:");
pw.println(" gestureID=" + mGestureId);

View File

@@ -121,6 +121,16 @@ public class RecentsAnimationCallbacks implements
});
}
@BinderThread
@Override
public void onTaskAppeared(RemoteAnimationTargetCompat app) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
listener.onTaskAppeared(app);
}
});
}
private final void onAnimationFinished(RecentsAnimationController controller) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
@@ -150,5 +160,10 @@ public class RecentsAnimationCallbacks implements
* Callback made whenever the recents animation is finished.
*/
default void onRecentsAnimationFinished(RecentsAnimationController controller) {}
/**
* Callback made when a task started from the recents is ready for an app transition.
*/
default void onTaskAppeared(RemoteAnimationTargetCompat app) {}
}
}

View File

@@ -22,6 +22,7 @@ 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.annotation.NonNull;
import android.os.SystemClock;
import android.util.Log;
import android.view.InputEvent;
@@ -34,6 +35,7 @@ import com.android.launcher3.util.Preconditions;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -107,6 +109,15 @@ public class RecentsAnimationController {
UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot());
}
/**
* Remove task remote animation target from
* {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}.
*/
@UiThread
public boolean removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) {
return mController.removeTask(target.taskId);
}
@UiThread
public void finishAnimationToHome() {
finishAndClear(true /* toRecents */, null, false /* sendUserLeaveHint */);