From 3b2eff1cc480d5c8940e1cc082422873f57cb19e Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Fri, 16 Sep 2022 00:04:16 +0000 Subject: Adjust caption observer for desktop transition Instead of specific transition types, just try to get captions and if it doesn't exist, make one. As we add more "source" windowing modes, we'll have to just check more listeners. This should hold-over until there's a centralized task-state manager. Also, try to create captions on "warm-starts" (TO_FRONT) so that apps that are in history before desktop-mode will get a caption. Bug: 246851689 Bug: 246637353 Test: enable shell-transitions and switch into/out-of desktop mode with varying sets of warm/cold-start apps Change-Id: If9e1ad35692b63bf8abd6185b037715b285645c9 --- .../wm/shell/freeform/FreeformTaskListener.java | 11 ++++-- .../freeform/FreeformTaskTransitionObserver.java | 39 +++++++++++++++++----- .../shell/fullscreen/FullscreenTaskListener.java | 11 ++++-- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java index ac95d4bc63d1..f58719b225a4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java @@ -191,15 +191,19 @@ public class FreeformTaskListener * * @param change the change of this task transition that needs to have the task layer as the * leash - * @return {@code true} if it adopts the window decoration; {@code false} otherwise + * @return {@code true} if it creates the window decoration; {@code false} otherwise */ - void createWindowDecoration( + boolean createWindowDecoration( TransitionInfo.Change change, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { final State state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash()); + if (state.mWindowDecoration != null) { + return false; + } state.mWindowDecoration = mWindowDecorationViewModel.createWindowDecoration( state.mTaskInfo, state.mLeash, startT, finishT); + return true; } /** @@ -222,6 +226,9 @@ public class FreeformTaskListener windowDecor = mWindowDecorOfVanishedTasks.removeReturnOld(taskInfo.taskId); } + if (windowDecor == null) { + return null; + } mWindowDecorationViewModel.setupWindowDecorationForTransition( taskInfo, startT, finishT, windowDecor); return windowDecor; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java index a780ec102ea9..17d60671e964 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java @@ -26,6 +26,7 @@ import android.util.Log; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.TransitionInfo; +import android.window.WindowContainerToken; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; @@ -80,6 +81,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs @NonNull SurfaceControl.Transaction startT, @NonNull SurfaceControl.Transaction finishT) { final ArrayList windowDecors = new ArrayList<>(); + final ArrayList taskParents = new ArrayList<>(); for (TransitionInfo.Change change : info.getChanges()) { if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) { continue; @@ -89,9 +91,22 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs if (taskInfo == null || taskInfo.taskId == -1) { continue; } + // Filter out non-leaf tasks. Freeform/fullscreen don't nest tasks, but split-screen + // does, so this prevents adding duplicate captions in that scenario. + if (change.getParent() != null + && info.getChange(change.getParent()).getTaskInfo() != null) { + // This logic relies on 2 assumptions: 1 is that child tasks will be visited before + // parents (due to how z-order works). 2 is that no non-tasks are interleaved + // between tasks (hierarchically). + taskParents.add(change.getContainer()); + } + if (taskParents.contains(change.getContainer())) { + continue; + } switch (change.getMode()) { case WindowManager.TRANSIT_OPEN: + case WindowManager.TRANSIT_TO_FRONT: onOpenTransitionReady(change, startT, finishT); break; case WindowManager.TRANSIT_CLOSE: { @@ -154,20 +169,28 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs boolean adopted = false; final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); - if (type == Transitions.TRANSIT_MAXIMIZE - && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { + if (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { windowDecor = mFreeformTaskListener.giveWindowDecoration( change.getTaskInfo(), startT, finishT); - adopted = mFullscreenTaskListener.adoptWindowDecoration( - change, startT, finishT, windowDecor); + if (windowDecor != null) { + adopted = mFullscreenTaskListener.adoptWindowDecoration( + change, startT, finishT, windowDecor); + } else { + // will return false if it already has the window decor. + adopted = mFullscreenTaskListener.createWindowDecoration(change, startT, finishT); + } } - if (type == Transitions.TRANSIT_RESTORE_FROM_MAXIMIZE - && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { + if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { windowDecor = mFullscreenTaskListener.giveWindowDecoration( change.getTaskInfo(), startT, finishT); - adopted = mFreeformTaskListener.adoptWindowDecoration( - change, startT, finishT, windowDecor); + if (windowDecor != null) { + adopted = mFreeformTaskListener.adoptWindowDecoration( + change, startT, finishT, windowDecor); + } else { + // will return false if it already has the window decor. + adopted = mFreeformTaskListener.createWindowDecoration(change, startT, finishT); + } } if (!adopted) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java index 7d1259a732c9..76e296bb8c61 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java @@ -173,16 +173,23 @@ public class FullscreenTaskListener * * @param change the change of this task transition that needs to have the task layer as the * leash + * @return {@code true} if a decoration was actually created. */ - public void createWindowDecoration(TransitionInfo.Change change, + public boolean createWindowDecoration(TransitionInfo.Change change, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { final State state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash()); - if (!mWindowDecorViewModelOptional.isPresent()) return; + if (!mWindowDecorViewModelOptional.isPresent()) return false; + if (state.mWindowDecoration != null) { + // Already has a decoration. + return false; + } T newWindowDecor = mWindowDecorViewModelOptional.get().createWindowDecoration( state.mTaskInfo, state.mLeash, startT, finishT); if (newWindowDecor != null) { state.mWindowDecoration = newWindowDecor; + return true; } + return false; } /** -- cgit v1.2.3-59-g8ed1b