summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java102
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java9
2 files changed, 80 insertions, 31 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index e5e06df003c9..8723f9b0181d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -35,6 +35,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
+import android.util.IntArray;
import android.util.Pair;
import android.util.Slog;
import android.view.Display;
@@ -422,26 +423,28 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// About layering: we divide up the "layer space" into 3 regions (each the size of
// the change count). This lets us categorize things into above/below/between
// while maintaining their relative ordering.
+ final int belowLayers = info.getChanges().size();
+ final int aboveLayers = info.getChanges().size() * 3;
for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change change = info.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (TransitionUtil.isWallpaper(change)) {
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
// wallpapers go into the "below" layer space
- info.getChanges().size() - i, info, t, mLeashMap);
+ belowLayers - i, info, t, mLeashMap);
wallpapers.add(target);
// Make all the wallpapers opaque since we want them visible from the start
t.setAlpha(target.leash, 1);
} else if (leafTaskFilter.test(change)) {
// start by putting everything into the "below" layer space.
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
- info.getChanges().size() - i, info, t, mLeashMap);
+ belowLayers - i, info, t, mLeashMap);
apps.add(target);
if (TransitionUtil.isClosingType(change.getMode())) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " adding pausing taskId=%d", taskInfo.taskId);
+ " adding pausing leaf taskId=%d", taskInfo.taskId);
// raise closing (pausing) task to "above" layer so it isn't covered
- t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ t.setLayer(target.leash, aboveLayers - i);
mPausingTasks.add(new TaskState(change, target.leash));
if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
// This can only happen if we have a separate recents/home (3p launcher)
@@ -454,17 +457,32 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
} else if (taskInfo != null
&& taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
// There's a 3p launcher, so make sure recents goes above that.
- t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ t.setLayer(target.leash, aboveLayers - i);
} else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
// do nothing
} else if (TransitionUtil.isOpeningType(change.getMode())) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " adding opening taskId=%d", taskInfo.taskId);
+ " adding opening leaf taskId=%d", taskInfo.taskId);
mOpeningTasks.add(new TaskState(change, target.leash));
}
+ } else if (taskInfo != null && TransitionInfo.isIndependent(change, info)) {
+ // Root tasks
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " adding pausing taskId=%d", taskInfo.taskId);
+ // raise closing (pausing) task to "above" layer so it isn't covered
+ t.setLayer(change.getLeash(), aboveLayers - i);
+ mPausingTasks.add(new TaskState(change, null /* leash */));
+ } else if (TransitionUtil.isOpeningType(change.getMode())) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " adding opening taskId=%d", taskInfo.taskId);
+ // Put into the "below" layer space.
+ t.setLayer(change.getLeash(), belowLayers - i);
+ mOpeningTasks.add(new TaskState(change, null /* leash */));
+ }
} else if (TransitionUtil.isDividerBar(change)) {
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
- info.getChanges().size() - i, info, t, mLeashMap);
+ belowLayers - i, info, t, mLeashMap);
// Add this as a app and we will separate them on launcher side by window type.
apps.add(target);
}
@@ -519,7 +537,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.merge", mInstanceId);
+ // Keep all tasks in one list because order matters.
ArrayList<TransitionInfo.Change> openingTasks = null;
+ IntArray openingTaskIsLeafs = null;
ArrayList<TransitionInfo.Change> closingTasks = null;
mOpeningSeparateHome = false;
TransitionInfo.Change recentsOpening = null;
@@ -538,25 +558,29 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
cancel("task #" + taskInfo.taskId + " is always_on_top");
return;
}
- hasTaskChange = hasTaskChange || taskInfo != null;
+ final boolean isRootTask = taskInfo != null
+ && TransitionInfo.isIndependent(change, info);
+ hasTaskChange = hasTaskChange || isRootTask;
final boolean isLeafTask = leafTaskFilter.test(change);
if (TransitionUtil.isOpeningType(change.getMode())) {
if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
recentsOpening = change;
- } else if (isLeafTask) {
- if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ } else if (isRootTask || isLeafTask) {
+ if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
// This is usually a 3p launcher
mOpeningSeparateHome = true;
}
if (openingTasks == null) {
openingTasks = new ArrayList<>();
+ openingTaskIsLeafs = new IntArray();
}
openingTasks.add(change);
+ openingTaskIsLeafs.add(isLeafTask ? 1 : 0);
}
} else if (TransitionUtil.isClosingType(change.getMode())) {
if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
foundRecentsClosing = true;
- } else if (isLeafTask) {
+ } else if (isRootTask || isLeafTask) {
if (closingTasks == null) {
closingTasks = new ArrayList<>();
}
@@ -622,7 +646,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
final TaskState openingTask = mOpeningTasks.remove(openingIdx);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " pausing opening taskId=%d", openingTask.mTaskInfo.taskId);
+ " pausing opening %staskId=%d", openingTask.isLeaf() ? "leaf " : "",
+ openingTask.mTaskInfo.taskId);
mPausingTasks.add(openingTask);
didMergeThings = true;
}
@@ -632,35 +657,55 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// Switching to some new tasks, add to mOpening and remove from mPausing. Also,
// enter NEW_TASK state since this will start the switch-to animation.
final int layer = mInfo.getChanges().size() * 3;
- appearedTargets = new RemoteAnimationTarget[openingTasks.size()];
+ int openingLeafCount = 0;
+ for (int i = 0; i < openingTaskIsLeafs.size(); ++i) {
+ openingLeafCount += openingTaskIsLeafs.get(i);
+ }
+ if (openingLeafCount > 0) {
+ appearedTargets = new RemoteAnimationTarget[openingLeafCount];
+ }
+ int nextTargetIdx = 0;
for (int i = 0; i < openingTasks.size(); ++i) {
final TransitionInfo.Change change = openingTasks.get(i);
+ final boolean isLeaf = openingTaskIsLeafs.get(i) == 1;
int pausingIdx = TaskState.indexOf(mPausingTasks, change);
if (pausingIdx >= 0) {
// Something is showing/opening a previously-pausing app.
- appearedTargets[i] = TransitionUtil.newTarget(
- change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ if (isLeaf) {
+ appearedTargets[nextTargetIdx++] = TransitionUtil.newTarget(
+ change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ }
final TaskState pausingTask = mPausingTasks.remove(pausingIdx);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " opening pausing taskId=%d", pausingTask.mTaskInfo.taskId);
+ " opening pausing %staskId=%d", isLeaf ? "leaf " : "",
+ pausingTask.mTaskInfo.taskId);
mOpeningTasks.add(pausingTask);
// Setup hides opening tasks initially, so make it visible again (since we
// are already showing it).
t.show(change.getLeash());
t.setAlpha(change.getLeash(), 1.f);
- } else {
- // We are receiving new opening tasks, so convert to onTasksAppeared.
- appearedTargets[i] = TransitionUtil.newTarget(
+ } else if (isLeaf) {
+ // We are receiving new opening leaf tasks, so convert to onTasksAppeared.
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(
change, layer, info, t, mLeashMap);
+ appearedTargets[nextTargetIdx++] = target;
// reparent into the original `mInfo` since that's where we are animating.
final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
- t.reparent(appearedTargets[i].leash, mInfo.getRoot(rootIdx).getLeash());
- t.setLayer(appearedTargets[i].leash, layer);
+ t.reparent(target.leash, mInfo.getRoot(rootIdx).getLeash());
+ t.setLayer(target.leash, layer);
// Hide the animation leash, let listener show it.
- t.hide(appearedTargets[i].leash);
+ t.hide(target.leash);
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " opening new leaf taskId=%d", target.taskId);
+ mOpeningTasks.add(new TaskState(change, target.leash));
+ } else {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " opening new taskId=%d", appearedTargets[i].taskId);
- mOpeningTasks.add(new TaskState(change, appearedTargets[i].leash));
+ " opening new taskId=%d", change.getTaskInfo().taskId);
+ t.setLayer(change.getLeash(), layer);
+ // Setup hides opening tasks initially, so make it visible since recents
+ // is only animating the leafs.
+ t.show(change.getLeash());
+ mOpeningTasks.add(new TaskState(change, null));
}
}
didMergeThings = true;
@@ -845,7 +890,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
t.show(mOpeningTasks.get(i).mTaskSurface);
}
for (int i = 0; i < mPausingTasks.size(); ++i) {
- if (!sendUserLeaveHint) {
+ if (!sendUserLeaveHint && mPausingTasks.get(i).isLeaf()) {
// This means recents is not *actually* finishing, so of course we gotta
// do special stuff in WMCore to accommodate.
wct.setDoNotPip(mPausingTasks.get(i).mToken);
@@ -924,7 +969,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
/** The surface/leash of the task provided by Core. */
SurfaceControl mTaskSurface;
- /** The (local) animation-leash created for this task. */
+ /** The (local) animation-leash created for this task. Only non-null for leafs. */
+ @Nullable
SurfaceControl mLeash;
TaskState(TransitionInfo.Change change, SurfaceControl leash) {
@@ -943,6 +989,10 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
return -1;
}
+ boolean isLeaf() {
+ return mLeash != null;
+ }
+
public String toString() {
return "" + mToken + " : " + mLeash;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
index 143b42a1ec96..c33a633f2068 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
@@ -121,15 +121,14 @@ public class TransitionUtil {
@Override
public boolean test(TransitionInfo.Change change) {
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo == null) return false;
// Children always come before parent since changes are in top-to-bottom z-order.
- if ((taskInfo == null) || mChildTaskTargets.get(taskInfo.taskId)) {
- // has children, so not a leaf. Skip.
- return false;
- }
+ boolean hasChildren = mChildTaskTargets.get(taskInfo.taskId);
if (taskInfo.hasParentTask()) {
mChildTaskTargets.put(taskInfo.parentTaskId, true);
}
- return true;
+ // If it has children, it's not a leaf.
+ return !hasChildren;
}
}