diff options
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java | 102 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java | 9 | 
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;          }      }  |