diff options
9 files changed, 131 insertions, 564 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java index 7c9cabde9c8d..7d0c4bd19a43 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java @@ -292,17 +292,17 @@ public abstract class WMShellBaseModule { // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} @BindsOptionalOf @DynamicOverride - abstract FullscreenTaskListener<?> optionalFullscreenTaskListener(); + abstract FullscreenTaskListener optionalFullscreenTaskListener(); @WMSingleton @Provides - static FullscreenTaskListener<?> provideFullscreenTaskListener( - @DynamicOverride Optional<FullscreenTaskListener<?>> fullscreenTaskListener, + static FullscreenTaskListener provideFullscreenTaskListener( + @DynamicOverride Optional<FullscreenTaskListener> fullscreenTaskListener, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, Optional<RecentTasksController> recentTasksOptional, - Optional<WindowDecorViewModel<?>> windowDecorViewModelOptional) { + Optional<WindowDecorViewModel> windowDecorViewModelOptional) { if (fullscreenTaskListener.isPresent()) { return fullscreenTaskListener.get(); } else { @@ -316,7 +316,7 @@ public abstract class WMShellBaseModule { // @BindsOptionalOf - abstract WindowDecorViewModel<?> optionalWindowDecorViewModel(); + abstract WindowDecorViewModel optionalWindowDecorViewModel(); // // Unfold transition @@ -768,7 +768,7 @@ public abstract class WMShellBaseModule { Optional<SplitScreenController> splitScreenOptional, Optional<Pip> pipOptional, Optional<PipTouchHandler> pipTouchHandlerOptional, - FullscreenTaskListener<?> fullscreenTaskListener, + FullscreenTaskListener fullscreenTaskListener, Optional<UnfoldAnimationController> unfoldAnimationController, Optional<UnfoldTransitionHandler> unfoldTransitionHandler, Optional<FreeformComponents> freeformComponents, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 47b665970d28..461d7dcf30ad 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -55,7 +55,6 @@ import com.android.wm.shell.freeform.FreeformComponents; import com.android.wm.shell.freeform.FreeformTaskListener; import com.android.wm.shell.freeform.FreeformTaskTransitionHandler; import com.android.wm.shell.freeform.FreeformTaskTransitionObserver; -import com.android.wm.shell.fullscreen.FullscreenTaskListener; import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.Pip; @@ -183,7 +182,7 @@ public abstract class WMShellModule { @WMSingleton @Provides - static WindowDecorViewModel<?> provideWindowDecorViewModel( + static WindowDecorViewModel provideWindowDecorViewModel( Context context, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, @@ -209,7 +208,7 @@ public abstract class WMShellModule { @Provides @DynamicOverride static FreeformComponents provideFreeformComponents( - FreeformTaskListener<?> taskListener, + FreeformTaskListener taskListener, FreeformTaskTransitionHandler transitionHandler, FreeformTaskTransitionObserver transitionObserver) { return new FreeformComponents( @@ -218,18 +217,18 @@ public abstract class WMShellModule { @WMSingleton @Provides - static FreeformTaskListener<?> provideFreeformTaskListener( + static FreeformTaskListener provideFreeformTaskListener( Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<DesktopModeTaskRepository> desktopModeTaskRepository, - WindowDecorViewModel<?> windowDecorViewModel) { + WindowDecorViewModel windowDecorViewModel) { // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic // override for this controller from the base module ShellInit init = FreeformComponents.isFreeformEnabled(context) ? shellInit : null; - return new FreeformTaskListener<>(init, shellTaskOrganizer, desktopModeTaskRepository, + return new FreeformTaskListener(init, shellTaskOrganizer, desktopModeTaskRepository, windowDecorViewModel); } @@ -238,7 +237,7 @@ public abstract class WMShellModule { static FreeformTaskTransitionHandler provideFreeformTaskTransitionHandler( ShellInit shellInit, Transitions transitions, - WindowDecorViewModel<?> windowDecorViewModel) { + WindowDecorViewModel windowDecorViewModel) { return new FreeformTaskTransitionHandler(shellInit, transitions, windowDecorViewModel); } @@ -248,10 +247,9 @@ public abstract class WMShellModule { Context context, ShellInit shellInit, Transitions transitions, - FullscreenTaskListener<?> fullscreenTaskListener, - FreeformTaskListener<?> freeformTaskListener) { + WindowDecorViewModel windowDecorViewModel) { return new FreeformTaskTransitionObserver( - context, shellInit, transitions, fullscreenTaskListener, freeformTaskListener); + context, shellInit, transitions, windowDecorViewModel); } // 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 e2d5a499d1e1..f82a34621262 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 @@ -19,12 +19,8 @@ package com.android.wm.shell.freeform; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FREEFORM; import android.app.ActivityManager.RunningTaskInfo; -import android.util.Log; import android.util.SparseArray; import android.view.SurfaceControl; -import android.window.TransitionInfo; - -import androidx.annotation.Nullable; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.ShellTaskOrganizer; @@ -41,31 +37,26 @@ import java.util.Optional; /** * {@link ShellTaskOrganizer.TaskListener} for {@link * ShellTaskOrganizer#TASK_LISTENER_TYPE_FREEFORM}. - * - * @param <T> the type of window decoration instance */ -public class FreeformTaskListener<T extends AutoCloseable> - implements ShellTaskOrganizer.TaskListener { +public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener { private static final String TAG = "FreeformTaskListener"; private final ShellTaskOrganizer mShellTaskOrganizer; private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository; - private final WindowDecorViewModel<T> mWindowDecorationViewModel; + private final WindowDecorViewModel mWindowDecorationViewModel; - private final SparseArray<State<T>> mTasks = new SparseArray<>(); - private final SparseArray<T> mWindowDecorOfVanishedTasks = new SparseArray<>(); + private final SparseArray<State> mTasks = new SparseArray<>(); - private static class State<T extends AutoCloseable> { + private static class State { RunningTaskInfo mTaskInfo; SurfaceControl mLeash; - T mWindowDecoration; } public FreeformTaskListener( ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<DesktopModeTaskRepository> desktopModeTaskRepository, - WindowDecorViewModel<T> windowDecorationViewModel) { + WindowDecorViewModel windowDecorationViewModel) { mShellTaskOrganizer = shellTaskOrganizer; mWindowDecorationViewModel = windowDecorationViewModel; mDesktopModeTaskRepository = desktopModeTaskRepository; @@ -80,13 +71,18 @@ public class FreeformTaskListener<T extends AutoCloseable> @Override public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { + if (mTasks.get(taskInfo.taskId) != null) { + throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId); + } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Appeared: #%d", taskInfo.taskId); - final State<T> state = createOrUpdateTaskState(taskInfo, leash); + final State state = new State(); + state.mTaskInfo = taskInfo; + state.mLeash = leash; + mTasks.put(taskInfo.taskId, state); if (!Transitions.ENABLE_SHELL_TRANSITIONS) { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); - state.mWindowDecoration = - mWindowDecorationViewModel.createWindowDecoration(taskInfo, leash, t, t); + mWindowDecorationViewModel.createWindowDecoration(taskInfo, leash, t, t); t.apply(); } @@ -97,28 +93,8 @@ public class FreeformTaskListener<T extends AutoCloseable> } } - private State<T> createOrUpdateTaskState(RunningTaskInfo taskInfo, SurfaceControl leash) { - State<T> state = mTasks.get(taskInfo.taskId); - if (state != null) { - updateTaskInfo(taskInfo); - return state; - } - - state = new State<>(); - state.mTaskInfo = taskInfo; - state.mLeash = leash; - mTasks.put(taskInfo.taskId, state); - - return state; - } - @Override public void onTaskVanished(RunningTaskInfo taskInfo) { - final State<T> state = mTasks.get(taskInfo.taskId); - if (state == null) { - // This is possible if the transition happens before this method. - return; - } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Vanished: #%d", taskInfo.taskId); mTasks.remove(taskInfo.taskId); @@ -129,26 +105,18 @@ public class FreeformTaskListener<T extends AutoCloseable> mDesktopModeTaskRepository.ifPresent(it -> it.removeActiveTask(taskInfo.taskId)); } - if (Transitions.ENABLE_SHELL_TRANSITIONS) { - // Save window decorations of closing tasks so that we can hand them over to the - // transition system if this method happens before the transition. In case where the - // transition didn't happen, it'd be cleared when the next transition finished. - if (state.mWindowDecoration != null) { - mWindowDecorOfVanishedTasks.put(taskInfo.taskId, state.mWindowDecoration); - } - return; + if (!Transitions.ENABLE_SHELL_TRANSITIONS) { + mWindowDecorationViewModel.destroyWindowDecoration(taskInfo); } - releaseWindowDecor(state.mWindowDecoration); } @Override public void onTaskInfoChanged(RunningTaskInfo taskInfo) { - final State<T> state = updateTaskInfo(taskInfo); + final State state = mTasks.get(taskInfo.taskId); + state.mTaskInfo = taskInfo; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Info Changed: #%d", taskInfo.taskId); - if (state.mWindowDecoration != null) { - mWindowDecorationViewModel.onTaskInfoChanged(state.mTaskInfo, state.mWindowDecoration); - } + mWindowDecorationViewModel.onTaskInfoChanged(state.mTaskInfo); if (DesktopModeStatus.IS_SUPPORTED) { if (taskInfo.isVisible) { @@ -159,15 +127,6 @@ public class FreeformTaskListener<T extends AutoCloseable> } } - private State<T> updateTaskInfo(RunningTaskInfo taskInfo) { - final State<T> state = mTasks.get(taskInfo.taskId); - if (state == null) { - throw new RuntimeException("Task info changed before appearing: #" + taskInfo.taskId); - } - state.mTaskInfo = taskInfo; - return state; - } - @Override public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) { b.setParent(findTaskSurface(taskId)); @@ -186,103 +145,6 @@ public class FreeformTaskListener<T extends AutoCloseable> return mTasks.get(taskId).mLeash; } - /** - * Creates a window decoration for a transition. - * - * @param change the change of this task transition that needs to have the task layer as the - * leash - * @return {@code true} if it creates the window decoration; {@code false} otherwise - */ - 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; - } - - /** - * Gives out the ownership of the task's window decoration. The given task is leaving (of has - * left) this task listener. This is the transition system asking for the ownership. - * - * @param taskInfo the maximizing task - * @return the window decor of the maximizing task if any - */ - T giveWindowDecoration( - RunningTaskInfo taskInfo, - SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT) { - T windowDecor; - final State<T> state = mTasks.get(taskInfo.taskId); - if (state != null) { - windowDecor = state.mWindowDecoration; - state.mWindowDecoration = null; - } else { - windowDecor = - mWindowDecorOfVanishedTasks.removeReturnOld(taskInfo.taskId); - } - if (windowDecor == null) { - return null; - } - mWindowDecorationViewModel.setupWindowDecorationForTransition( - taskInfo, startT, finishT, windowDecor); - return windowDecor; - } - - /** - * Adopt the incoming window decoration and lets the window decoration prepare for a transition. - * - * @param change the change of this task transition that needs to have the task layer as the - * leash - * @param startT the start transaction of this transition - * @param finishT the finish transaction of this transition - * @param windowDecor the window decoration to adopt - * @return {@code true} if it adopts the window decoration; {@code false} otherwise - */ - boolean adoptWindowDecoration( - TransitionInfo.Change change, - SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT, - @Nullable AutoCloseable windowDecor) { - final State<T> state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash()); - state.mWindowDecoration = mWindowDecorationViewModel.adoptWindowDecoration(windowDecor); - if (state.mWindowDecoration != null) { - mWindowDecorationViewModel.setupWindowDecorationForTransition( - state.mTaskInfo, startT, finishT, state.mWindowDecoration); - return true; - } else { - state.mWindowDecoration = mWindowDecorationViewModel.createWindowDecoration( - state.mTaskInfo, state.mLeash, startT, finishT); - return false; - } - } - - void onTaskTransitionFinished() { - if (mWindowDecorOfVanishedTasks.size() == 0) { - return; - } - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, - "Clearing window decors of vanished tasks. There could be visual defects " - + "if any of them is used later in transitions."); - for (int i = 0; i < mWindowDecorOfVanishedTasks.size(); ++i) { - releaseWindowDecor(mWindowDecorOfVanishedTasks.valueAt(i)); - } - mWindowDecorOfVanishedTasks.clear(); - } - - private void releaseWindowDecor(T windowDecor) { - try { - windowDecor.close(); - } catch (Exception e) { - Log.e(TAG, "Failed to release window decoration.", e); - } - } - @Override public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java index fd4c85fad77f..04fc79acadbd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java @@ -46,14 +46,14 @@ public class FreeformTaskTransitionHandler implements Transitions.TransitionHandler, FreeformTaskTransitionStarter { private final Transitions mTransitions; - private final WindowDecorViewModel<?> mWindowDecorViewModel; + private final WindowDecorViewModel mWindowDecorViewModel; private final List<IBinder> mPendingTransitionTokens = new ArrayList<>(); public FreeformTaskTransitionHandler( ShellInit shellInit, Transitions transitions, - WindowDecorViewModel<?> windowDecorViewModel) { + WindowDecorViewModel windowDecorViewModel) { mTransitions = transitions; mWindowDecorViewModel = windowDecorViewModel; if (Transitions.ENABLE_SHELL_TRANSITIONS) { 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 17d60671e964..f4888fbb2bb9 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 @@ -16,13 +16,9 @@ package com.android.wm.shell.freeform; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; - import android.app.ActivityManager; import android.content.Context; import android.os.IBinder; -import android.util.Log; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.TransitionInfo; @@ -31,9 +27,9 @@ import android.window.WindowContainerToken; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import com.android.wm.shell.fullscreen.FullscreenTaskListener; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; +import com.android.wm.shell.windowdecor.WindowDecorViewModel; import java.util.ArrayList; import java.util.Collections; @@ -47,23 +43,19 @@ import java.util.Map; * be a part of transitions. */ public class FreeformTaskTransitionObserver implements Transitions.TransitionObserver { - private static final String TAG = "FreeformTO"; - private final Transitions mTransitions; - private final FreeformTaskListener<?> mFreeformTaskListener; - private final FullscreenTaskListener<?> mFullscreenTaskListener; + private final WindowDecorViewModel mWindowDecorViewModel; - private final Map<IBinder, List<AutoCloseable>> mTransitionToWindowDecors = new HashMap<>(); + private final Map<IBinder, List<ActivityManager.RunningTaskInfo>> mTransitionToTaskInfo = + new HashMap<>(); public FreeformTaskTransitionObserver( Context context, ShellInit shellInit, Transitions transitions, - FullscreenTaskListener<?> fullscreenTaskListener, - FreeformTaskListener<?> freeformTaskListener) { + WindowDecorViewModel windowDecorViewModel) { mTransitions = transitions; - mFreeformTaskListener = freeformTaskListener; - mFullscreenTaskListener = fullscreenTaskListener; + mWindowDecorViewModel = windowDecorViewModel; if (Transitions.ENABLE_SHELL_TRANSITIONS && FreeformComponents.isFreeformEnabled(context)) { shellInit.addInitCallback(this::onInit, this); } @@ -80,7 +72,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT, @NonNull SurfaceControl.Transaction finishT) { - final ArrayList<AutoCloseable> windowDecors = new ArrayList<>(); + final ArrayList<ActivityManager.RunningTaskInfo> taskInfoList = new ArrayList<>(); final ArrayList<WindowContainerToken> taskParents = new ArrayList<>(); for (TransitionInfo.Change change : info.getChanges()) { if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) { @@ -110,92 +102,40 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs onOpenTransitionReady(change, startT, finishT); break; case WindowManager.TRANSIT_CLOSE: { - onCloseTransitionReady(change, windowDecors, startT, finishT); + taskInfoList.add(change.getTaskInfo()); + onCloseTransitionReady(change, startT, finishT); break; } case WindowManager.TRANSIT_CHANGE: - onChangeTransitionReady(info.getType(), change, startT, finishT); + onChangeTransitionReady(change, startT, finishT); break; } } - if (!windowDecors.isEmpty()) { - mTransitionToWindowDecors.put(transition, windowDecors); - } + mTransitionToTaskInfo.put(transition, taskInfoList); } private void onOpenTransitionReady( TransitionInfo.Change change, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - switch (change.getTaskInfo().getWindowingMode()){ - case WINDOWING_MODE_FREEFORM: - mFreeformTaskListener.createWindowDecoration(change, startT, finishT); - break; - case WINDOWING_MODE_FULLSCREEN: - mFullscreenTaskListener.createWindowDecoration(change, startT, finishT); - break; - } + mWindowDecorViewModel.createWindowDecoration( + change.getTaskInfo(), change.getLeash(), startT, finishT); } private void onCloseTransitionReady( TransitionInfo.Change change, - ArrayList<AutoCloseable> windowDecors, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - final AutoCloseable windowDecor; - switch (change.getTaskInfo().getWindowingMode()) { - case WINDOWING_MODE_FREEFORM: - windowDecor = mFreeformTaskListener.giveWindowDecoration(change.getTaskInfo(), - startT, finishT); - break; - case WINDOWING_MODE_FULLSCREEN: - windowDecor = mFullscreenTaskListener.giveWindowDecoration(change.getTaskInfo(), - startT, finishT); - break; - default: - windowDecor = null; - } - if (windowDecor != null) { - windowDecors.add(windowDecor); - } + mWindowDecorViewModel.setupWindowDecorationForTransition( + change.getTaskInfo(), startT, finishT); } private void onChangeTransitionReady( - int type, TransitionInfo.Change change, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - AutoCloseable windowDecor = null; - - boolean adopted = false; - final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); - if (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { - windowDecor = mFreeformTaskListener.giveWindowDecoration( - change.getTaskInfo(), startT, finishT); - 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 (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { - windowDecor = mFullscreenTaskListener.giveWindowDecoration( - change.getTaskInfo(), startT, finishT); - 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) { - releaseWindowDecor(windowDecor); - } + mWindowDecorViewModel.setupWindowDecorationForTransition( + change.getTaskInfo(), startT, finishT); } @Override @@ -203,43 +143,32 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs @Override public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) { - final List<AutoCloseable> windowDecorsOfMerged = mTransitionToWindowDecors.get(merged); - if (windowDecorsOfMerged == null) { + final List<ActivityManager.RunningTaskInfo> infoOfMerged = + mTransitionToTaskInfo.get(merged); + if (infoOfMerged == null) { // We are adding window decorations of the merged transition to them of the playing // transition so if there is none of them there is nothing to do. return; } - mTransitionToWindowDecors.remove(merged); + mTransitionToTaskInfo.remove(merged); - final List<AutoCloseable> windowDecorsOfPlaying = mTransitionToWindowDecors.get(playing); - if (windowDecorsOfPlaying != null) { - windowDecorsOfPlaying.addAll(windowDecorsOfMerged); + final List<ActivityManager.RunningTaskInfo> infoOfPlaying = + mTransitionToTaskInfo.get(playing); + if (infoOfPlaying != null) { + infoOfPlaying.addAll(infoOfMerged); } else { - mTransitionToWindowDecors.put(playing, windowDecorsOfMerged); + mTransitionToTaskInfo.put(playing, infoOfMerged); } } @Override public void onTransitionFinished(@NonNull IBinder transition, boolean aborted) { - final List<AutoCloseable> windowDecors = mTransitionToWindowDecors.getOrDefault( - transition, Collections.emptyList()); - mTransitionToWindowDecors.remove(transition); + final List<ActivityManager.RunningTaskInfo> taskInfo = + mTransitionToTaskInfo.getOrDefault(transition, Collections.emptyList()); + mTransitionToTaskInfo.remove(transition); - for (AutoCloseable windowDecor : windowDecors) { - releaseWindowDecor(windowDecor); - } - mFullscreenTaskListener.onTaskTransitionFinished(); - mFreeformTaskListener.onTaskTransitionFinished(); - } - - private static void releaseWindowDecor(AutoCloseable windowDecor) { - if (windowDecor == null) { - return; - } - try { - windowDecor.close(); - } catch (Exception e) { - Log.e(TAG, "Failed to release window decoration.", e); + for (int i = 0; i < taskInfo.size(); ++i) { + mWindowDecorViewModel.destroyWindowDecoration(taskInfo.get(i)); } } } 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 76e296bb8c61..75a4091c7d78 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 @@ -22,13 +22,10 @@ import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.graphics.Point; -import android.util.Log; import android.util.SparseArray; import android.view.SurfaceControl; -import android.window.TransitionInfo; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.ShellTaskOrganizer; @@ -46,23 +43,20 @@ import java.util.Optional; * Organizes tasks presented in {@link android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN}. * @param <T> the type of window decoration instance */ -public class FullscreenTaskListener<T extends AutoCloseable> - implements ShellTaskOrganizer.TaskListener { +public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { private static final String TAG = "FullscreenTaskListener"; private final ShellTaskOrganizer mShellTaskOrganizer; - private final SparseArray<State<T>> mTasks = new SparseArray<>(); - private final SparseArray<T> mWindowDecorOfVanishedTasks = new SparseArray<>(); + private final SparseArray<State> mTasks = new SparseArray<>(); - private static class State<T extends AutoCloseable> { + private static class State { RunningTaskInfo mTaskInfo; SurfaceControl mLeash; - T mWindowDecoration; } private final SyncTransactionQueue mSyncQueue; private final Optional<RecentTasksController> mRecentTasksOptional; - private final Optional<WindowDecorViewModel<T>> mWindowDecorViewModelOptional; + private final Optional<WindowDecorViewModel> mWindowDecorViewModelOptional; /** * This constructor is used by downstream products. */ @@ -75,7 +69,7 @@ public class FullscreenTaskListener<T extends AutoCloseable> ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, Optional<RecentTasksController> recentTasksOptional, - Optional<WindowDecorViewModel<T>> windowDecorViewModelOptional) { + Optional<WindowDecorViewModel> windowDecorViewModelOptional) { mShellTaskOrganizer = shellTaskOrganizer; mSyncQueue = syncQueue; mRecentTasksOptional = recentTasksOptional; @@ -98,21 +92,21 @@ public class FullscreenTaskListener<T extends AutoCloseable> ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", taskInfo.taskId); final Point positionInParent = taskInfo.positionInParent; - final State<T> state = new State(); + final State state = new State(); state.mLeash = leash; state.mTaskInfo = taskInfo; mTasks.put(taskInfo.taskId, state); if (Transitions.ENABLE_SHELL_TRANSITIONS) return; updateRecentsForVisibleFullscreenTask(taskInfo); + boolean createdWindowDecor = false; if (mWindowDecorViewModelOptional.isPresent()) { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); - state.mWindowDecoration = - mWindowDecorViewModelOptional.get().createWindowDecoration(taskInfo, - leash, t, t); + createdWindowDecor = mWindowDecorViewModelOptional.get() + .createWindowDecoration(taskInfo, leash, t, t); t.apply(); } - if (state.mWindowDecoration == null) { + if (!createdWindowDecor) { mSyncQueue.runInSync(t -> { // Reset several properties back to fullscreen (PiP, for example, leaves all these // properties in a bad state). @@ -127,12 +121,11 @@ public class FullscreenTaskListener<T extends AutoCloseable> @Override public void onTaskInfoChanged(RunningTaskInfo taskInfo) { - final State<T> state = mTasks.get(taskInfo.taskId); + final State state = mTasks.get(taskInfo.taskId); final Point oldPositionInParent = state.mTaskInfo.positionInParent; state.mTaskInfo = taskInfo; - if (state.mWindowDecoration != null) { - mWindowDecorViewModelOptional.get().onTaskInfoChanged( - state.mTaskInfo, state.mWindowDecoration); + if (mWindowDecorViewModelOptional.isPresent()) { + mWindowDecorViewModelOptional.get().onTaskInfoChanged(state.mTaskInfo); } if (Transitions.ENABLE_SHELL_TRANSITIONS) return; updateRecentsForVisibleFullscreenTask(taskInfo); @@ -147,160 +140,13 @@ public class FullscreenTaskListener<T extends AutoCloseable> @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { - final State<T> state = mTasks.get(taskInfo.taskId); - if (state == null) { - // This is possible if the transition happens before this method. - return; - } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d", taskInfo.taskId); mTasks.remove(taskInfo.taskId); - if (Transitions.ENABLE_SHELL_TRANSITIONS) { - // Save window decorations of closing tasks so that we can hand them over to the - // transition system if this method happens before the transition. In case where the - // transition didn't happen, it'd be cleared when the next transition finished. - if (state.mWindowDecoration != null) { - mWindowDecorOfVanishedTasks.put(taskInfo.taskId, state.mWindowDecoration); - } - return; - } - releaseWindowDecor(state.mWindowDecoration); - } - - /** - * Creates a window decoration for a transition. - * - * @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 boolean createWindowDecoration(TransitionInfo.Change change, - SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - final State<T> state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash()); - 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; - } - - /** - * Adopt the incoming window decoration and lets the window decoration prepare for a transition. - * - * @param change the change of this task transition that needs to have the task layer as the - * leash - * @param startT the start transaction of this transition - * @param finishT the finish transaction of this transition - * @param windowDecor the window decoration to adopt - * @return {@code true} if it adopts the window decoration; {@code false} otherwise - */ - public boolean adoptWindowDecoration( - TransitionInfo.Change change, - SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT, - @Nullable AutoCloseable windowDecor) { - if (!mWindowDecorViewModelOptional.isPresent()) { - return false; - } - final State<T> state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash()); - state.mWindowDecoration = mWindowDecorViewModelOptional.get().adoptWindowDecoration( - windowDecor); - if (state.mWindowDecoration != null) { - mWindowDecorViewModelOptional.get().setupWindowDecorationForTransition( - state.mTaskInfo, startT, finishT, state.mWindowDecoration); - return true; - } else { - T newWindowDecor = mWindowDecorViewModelOptional.get().createWindowDecoration( - state.mTaskInfo, state.mLeash, startT, finishT); - if (newWindowDecor != null) { - state.mWindowDecoration = newWindowDecor; - } - return false; - } - } - - /** - * Clear window decors of vanished tasks. - */ - public void onTaskTransitionFinished() { - if (mWindowDecorOfVanishedTasks.size() == 0) { - return; - } - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, - "Clearing window decors of vanished tasks. There could be visual defects " - + "if any of them is used later in transitions."); - for (int i = 0; i < mWindowDecorOfVanishedTasks.size(); ++i) { - releaseWindowDecor(mWindowDecorOfVanishedTasks.valueAt(i)); - } - mWindowDecorOfVanishedTasks.clear(); - } - - /** - * Gives out the ownership of the task's window decoration. The given task is leaving (of has - * left) this task listener. This is the transition system asking for the ownership. - * - * @param taskInfo the maximizing task - * @return the window decor of the maximizing task if any - */ - public T giveWindowDecoration( - ActivityManager.RunningTaskInfo taskInfo, - SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT) { - T windowDecor; - final State<T> state = mTasks.get(taskInfo.taskId); - if (state != null) { - windowDecor = state.mWindowDecoration; - state.mWindowDecoration = null; - } else { - windowDecor = - mWindowDecorOfVanishedTasks.removeReturnOld(taskInfo.taskId); - } - if (mWindowDecorViewModelOptional.isPresent() && windowDecor != null) { - mWindowDecorViewModelOptional.get().setupWindowDecorationForTransition( - taskInfo, startT, finishT, windowDecor); - } - - return windowDecor; - } - - private State<T> createOrUpdateTaskState(ActivityManager.RunningTaskInfo taskInfo, - SurfaceControl leash) { - State<T> state = mTasks.get(taskInfo.taskId); - if (state != null) { - updateTaskInfo(taskInfo); - return state; - } - - state = new State<T>(); - state.mTaskInfo = taskInfo; - state.mLeash = leash; - mTasks.put(taskInfo.taskId, state); - - return state; - } - - private State<T> updateTaskInfo(ActivityManager.RunningTaskInfo taskInfo) { - final State<T> state = mTasks.get(taskInfo.taskId); - state.mTaskInfo = taskInfo; - return state; - } - - private void releaseWindowDecor(T windowDecor) { - if (windowDecor == null) { - return; - } - try { - windowDecor.close(); - } catch (Exception e) { - Log.e(TAG, "Failed to release window decoration.", e); + if (Transitions.ENABLE_SHELL_TRANSITIONS) return; + if (mWindowDecorViewModelOptional.isPresent()) { + mWindowDecorViewModelOptional.get().destroyWindowDecoration(taskInfo); } } @@ -342,6 +188,4 @@ public class FullscreenTaskListener<T extends AutoCloseable> public String toString() { return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); } - - } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java index 9e49b51e1504..3df33f346e84 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java @@ -26,6 +26,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityTaskManager; import android.content.Context; import android.os.Handler; +import android.util.SparseArray; import android.view.Choreographer; import android.view.MotionEvent; import android.view.SurfaceControl; @@ -46,7 +47,7 @@ import com.android.wm.shell.transition.Transitions; * View model for the window decoration with a caption and shadows. Works with * {@link CaptionWindowDecoration}. */ -public class CaptionWindowDecorViewModel implements WindowDecorViewModel<CaptionWindowDecoration> { +public class CaptionWindowDecorViewModel implements WindowDecorViewModel { private final ActivityTaskManager mActivityTaskManager; private final ShellTaskOrganizer mTaskOrganizer; private final Context mContext; @@ -57,6 +58,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption private FreeformTaskTransitionStarter mTransitionStarter; private DesktopModeController mDesktopModeController; + private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>(); + public CaptionWindowDecorViewModel( Context context, Handler mainHandler, @@ -81,12 +84,12 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption } @Override - public CaptionWindowDecoration createWindowDecoration( + public boolean createWindowDecoration( ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - if (!shouldShowWindowDecor(taskInfo)) return null; + if (!shouldShowWindowDecor(taskInfo)) return false; final CaptionWindowDecoration windowDecoration = new CaptionWindowDecoration( mContext, mDisplayController, @@ -96,30 +99,24 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption mMainHandler, mMainChoreographer, mSyncQueue); + mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration); + TaskPositioner taskPositioner = new TaskPositioner(mTaskOrganizer, windowDecoration); CaptionTouchEventListener touchEventListener = new CaptionTouchEventListener(taskInfo, taskPositioner); windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); windowDecoration.setDragResizeCallback(taskPositioner); - setupWindowDecorationForTransition(taskInfo, startT, finishT, windowDecoration); + setupWindowDecorationForTransition(taskInfo, startT, finishT); setupCaptionColor(taskInfo, windowDecoration); - return windowDecoration; + return true; } @Override - public CaptionWindowDecoration adoptWindowDecoration(AutoCloseable windowDecor) { - if (!(windowDecor instanceof CaptionWindowDecoration)) return null; - final CaptionWindowDecoration captionWindowDecor = (CaptionWindowDecoration) windowDecor; - if (!shouldShowWindowDecor(captionWindowDecor.mTaskInfo)) { - return null; - } - return captionWindowDecor; - } + public void onTaskInfoChanged(RunningTaskInfo taskInfo) { + final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); + if (decoration == null) return; - @Override - public void onTaskInfoChanged(RunningTaskInfo taskInfo, CaptionWindowDecoration decoration) { decoration.relayout(taskInfo); - setupCaptionColor(taskInfo, decoration); } @@ -132,11 +129,22 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel<Caption public void setupWindowDecorationForTransition( RunningTaskInfo taskInfo, SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT, - CaptionWindowDecoration decoration) { + SurfaceControl.Transaction finishT) { + final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); + if (decoration == null) return; + decoration.relayout(taskInfo, startT, finishT); } + @Override + public void destroyWindowDecoration(RunningTaskInfo taskInfo) { + final CaptionWindowDecoration decoration = + mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId); + if (decoration == null) return; + + decoration.close(); + } + private class CaptionTouchEventListener implements View.OnClickListener, View.OnTouchListener { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java index d9697d288ab6..d7f71c8235f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java @@ -19,8 +19,6 @@ package com.android.wm.shell.windowdecor; import android.app.ActivityManager; import android.view.SurfaceControl; -import androidx.annotation.Nullable; - import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; /** @@ -28,10 +26,8 @@ import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; * customize {@link WindowDecoration}. Its implementations are responsible to interpret user's * interactions with UI widgets in window decorations and send corresponding requests to system * servers. - * - * @param <T> The actual decoration type */ -public interface WindowDecorViewModel<T extends AutoCloseable> { +public interface WindowDecorViewModel { /** * Sets the transition starter that starts freeform task transitions. @@ -50,29 +46,19 @@ public interface WindowDecorViewModel<T extends AutoCloseable> { * @param finishT the finish transaction to restore states after the transition * @return the window decoration object */ - @Nullable T createWindowDecoration( + boolean createWindowDecoration( ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT); /** - * Adopts the window decoration if possible. - * May be {@code null} if a window decor is not needed or the given one is incompatible. - * - * @param windowDecor the potential window decoration to adopt - * @return the window decoration if it can be adopted, or {@code null} otherwise. - */ - @Nullable T adoptWindowDecoration(@Nullable AutoCloseable windowDecor); - - /** * Notifies a task info update on the given task, with the window decoration created previously * for this task by {@link #createWindowDecoration}. * * @param taskInfo the new task info of the task - * @param windowDecoration the window decoration created for the task */ - void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo, T windowDecoration); + void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo); /** * Notifies a transition is about to start about the given task to give the window decoration a @@ -80,11 +66,16 @@ public interface WindowDecorViewModel<T extends AutoCloseable> { * * @param startT the start transaction to be applied before the transition * @param finishT the finish transaction to restore states after the transition - * @param windowDecoration the window decoration created for the task */ void setupWindowDecorationForTransition( ActivityManager.RunningTaskInfo taskInfo, SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT, - T windowDecoration); + SurfaceControl.Transaction finishT); + + /** + * Destroys the window decoration of the give task. + * + * @param taskInfo the info of the task + */ + void destroyWindowDecoration(ActivityManager.RunningTaskInfo taskInfo); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java index 0fd5cb081ea9..7068a84c3056 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java @@ -17,17 +17,10 @@ package com.android.wm.shell.freeform; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_OPEN; -import static com.android.wm.shell.transition.Transitions.TRANSIT_MAXIMIZE; -import static com.android.wm.shell.transition.Transitions.TRANSIT_RESTORE_FROM_MAXIMIZE; - -import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.same; @@ -44,9 +37,9 @@ import android.window.WindowContainerToken; import androidx.test.filters.SmallTest; -import com.android.wm.shell.fullscreen.FullscreenTaskListener; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; +import com.android.wm.shell.windowdecor.WindowDecorViewModel; import org.junit.Before; import org.junit.Test; @@ -65,9 +58,7 @@ public class FreeformTaskTransitionObserverTest { @Mock private Transitions mTransitions; @Mock - private FullscreenTaskListener<?> mFullscreenTaskListener; - @Mock - private FreeformTaskListener<?> mFreeformTaskListener; + private WindowDecorViewModel mWindowDecorViewModel; private FreeformTaskTransitionObserver mTransitionObserver; @@ -82,7 +73,7 @@ public class FreeformTaskTransitionObserverTest { doReturn(pm).when(context).getPackageManager(); mTransitionObserver = new FreeformTaskTransitionObserver( - context, mShellInit, mTransitions, mFullscreenTaskListener, mFreeformTaskListener); + context, mShellInit, mTransitions, mWindowDecorViewModel); if (Transitions.ENABLE_SHELL_TRANSITIONS) { final ArgumentCaptor<Runnable> initRunnableCaptor = ArgumentCaptor.forClass( Runnable.class); @@ -112,11 +103,12 @@ public class FreeformTaskTransitionObserverTest { mTransitionObserver.onTransitionReady(transition, info, startT, finishT); mTransitionObserver.onTransitionStarting(transition); - verify(mFreeformTaskListener).createWindowDecoration(change, startT, finishT); + verify(mWindowDecorViewModel).createWindowDecoration( + change.getTaskInfo(), change.getLeash(), startT, finishT); } @Test - public void testObtainsWindowDecorOnCloseTransition_freeform() { + public void testPreparesWindowDecorOnCloseTransition_freeform() { final TransitionInfo.Change change = createChange(TRANSIT_CLOSE, 1, WINDOWING_MODE_FREEFORM); final TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0); @@ -128,7 +120,8 @@ public class FreeformTaskTransitionObserverTest { mTransitionObserver.onTransitionReady(transition, info, startT, finishT); mTransitionObserver.onTransitionStarting(transition); - verify(mFreeformTaskListener).giveWindowDecoration(change.getTaskInfo(), startT, finishT); + verify(mWindowDecorViewModel).setupWindowDecorationForTransition( + change.getTaskInfo(), startT, finishT); } @Test @@ -138,17 +131,13 @@ public class FreeformTaskTransitionObserverTest { final TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0); info.addChange(change); - final AutoCloseable windowDecor = mock(AutoCloseable.class); - doReturn(windowDecor).when(mFreeformTaskListener).giveWindowDecoration( - eq(change.getTaskInfo()), any(), any()); - final IBinder transition = mock(IBinder.class); final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); mTransitionObserver.onTransitionReady(transition, info, startT, finishT); mTransitionObserver.onTransitionStarting(transition); - verify(windowDecor, never()).close(); + verify(mWindowDecorViewModel, never()).destroyWindowDecoration(change.getTaskInfo()); } @Test @@ -159,8 +148,6 @@ public class FreeformTaskTransitionObserverTest { info.addChange(change); final AutoCloseable windowDecor = mock(AutoCloseable.class); - doReturn(windowDecor).when(mFreeformTaskListener).giveWindowDecoration( - eq(change.getTaskInfo()), any(), any()); final IBinder transition = mock(IBinder.class); final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); @@ -169,7 +156,7 @@ public class FreeformTaskTransitionObserverTest { mTransitionObserver.onTransitionStarting(transition); mTransitionObserver.onTransitionFinished(transition, false); - verify(windowDecor).close(); + verify(mWindowDecorViewModel).destroyWindowDecoration(change.getTaskInfo()); } @Test @@ -192,10 +179,6 @@ public class FreeformTaskTransitionObserverTest { final TransitionInfo info2 = new TransitionInfo(TRANSIT_CLOSE, 0); info2.addChange(change2); - final AutoCloseable windowDecor2 = mock(AutoCloseable.class); - doReturn(windowDecor2).when(mFreeformTaskListener).giveWindowDecoration( - eq(change2.getTaskInfo()), any(), any()); - final IBinder transition2 = mock(IBinder.class); final SurfaceControl.Transaction startT2 = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT2 = mock(SurfaceControl.Transaction.class); @@ -204,7 +187,7 @@ public class FreeformTaskTransitionObserverTest { mTransitionObserver.onTransitionFinished(transition1, false); - verify(windowDecor2).close(); + verify(mWindowDecorViewModel).destroyWindowDecoration(change2.getTaskInfo()); } @Test @@ -215,10 +198,6 @@ public class FreeformTaskTransitionObserverTest { final TransitionInfo info1 = new TransitionInfo(TRANSIT_CLOSE, 0); info1.addChange(change1); - final AutoCloseable windowDecor1 = mock(AutoCloseable.class); - doReturn(windowDecor1).when(mFreeformTaskListener).giveWindowDecoration( - eq(change1.getTaskInfo()), any(), any()); - final IBinder transition1 = mock(IBinder.class); final SurfaceControl.Transaction startT1 = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT1 = mock(SurfaceControl.Transaction.class); @@ -231,10 +210,6 @@ public class FreeformTaskTransitionObserverTest { final TransitionInfo info2 = new TransitionInfo(TRANSIT_CLOSE, 0); info2.addChange(change2); - final AutoCloseable windowDecor2 = mock(AutoCloseable.class); - doReturn(windowDecor2).when(mFreeformTaskListener).giveWindowDecoration( - eq(change2.getTaskInfo()), any(), any()); - final IBinder transition2 = mock(IBinder.class); final SurfaceControl.Transaction startT2 = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT2 = mock(SurfaceControl.Transaction.class); @@ -243,48 +218,8 @@ public class FreeformTaskTransitionObserverTest { mTransitionObserver.onTransitionFinished(transition1, false); - verify(windowDecor1).close(); - verify(windowDecor2).close(); - } - - @Test - public void testTransfersWindowDecorOnMaximize() { - final TransitionInfo.Change change = - createChange(TRANSIT_CHANGE, 1, WINDOWING_MODE_FULLSCREEN); - final TransitionInfo info = new TransitionInfo(TRANSIT_MAXIMIZE, 0); - info.addChange(change); - - final AutoCloseable windowDecor = mock(AutoCloseable.class); - doReturn(windowDecor).when(mFreeformTaskListener).giveWindowDecoration( - eq(change.getTaskInfo()), any(), any()); - - final IBinder transition = mock(IBinder.class); - final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); - final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); - mTransitionObserver.onTransitionReady(transition, info, startT, finishT); - mTransitionObserver.onTransitionStarting(transition); - - verify(mFreeformTaskListener).giveWindowDecoration(change.getTaskInfo(), startT, finishT); - verify(mFullscreenTaskListener).adoptWindowDecoration( - eq(change), same(startT), same(finishT), any()); - } - - @Test - public void testTransfersWindowDecorOnRestoreFromMaximize() { - final TransitionInfo.Change change = - createChange(TRANSIT_CHANGE, 1, WINDOWING_MODE_FREEFORM); - final TransitionInfo info = new TransitionInfo(TRANSIT_RESTORE_FROM_MAXIMIZE, 0); - info.addChange(change); - - final IBinder transition = mock(IBinder.class); - final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); - final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); - mTransitionObserver.onTransitionReady(transition, info, startT, finishT); - mTransitionObserver.onTransitionStarting(transition); - - verify(mFullscreenTaskListener).giveWindowDecoration(change.getTaskInfo(), startT, finishT); - verify(mFreeformTaskListener).adoptWindowDecoration( - eq(change), same(startT), same(finishT), any()); + verify(mWindowDecorViewModel).destroyWindowDecoration(change1.getTaskInfo()); + verify(mWindowDecorViewModel).destroyWindowDecoration(change2.getTaskInfo()); } private static TransitionInfo.Change createChange(int mode, int taskId, int windowingMode) { |