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
This commit is contained in:
Evan Rosky
2022-09-16 00:04:16 +00:00
parent 3493f307ba
commit 3b2eff1cc4
3 changed files with 49 additions and 12 deletions

View File

@@ -191,15 +191,19 @@ public class FreeformTaskListener<T extends AutoCloseable>
*
* @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<T> 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<T extends AutoCloseable>
windowDecor =
mWindowDecorOfVanishedTasks.removeReturnOld(taskInfo.taskId);
}
if (windowDecor == null) {
return null;
}
mWindowDecorationViewModel.setupWindowDecorationForTransition(
taskInfo, startT, finishT, windowDecor);
return windowDecor;

View File

@@ -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<AutoCloseable> windowDecors = new ArrayList<>();
final ArrayList<WindowContainerToken> 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) {

View File

@@ -173,16 +173,23 @@ public class FullscreenTaskListener<T extends AutoCloseable>
*
* @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<T> 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;
}
/**