Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34bba31a authored by Jorge Gil's avatar Jorge Gil Committed by Orhan Uysal
Browse files

Destroy window decorations of closing non-visible tasks

Uses onTaskVanished to detect non-visible closing tasks that won't be
included in shell transitions, which is the usual path for decorations
to be destroyed.

Bug: 296921167
Bug: 338430613
Bug: 323251951
Test: close invisible tasks (e.g. from overview). Dump WMShell to verify
decoration is no longer held by the view model. Reference the memory
regeression bug linked above. See that the regression is fixed.

Change-Id: Id4538ac41b77a4c81454d6837db4ffaff8c2b0e5
parent c913a319
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
                repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId, false);
            });
        }

        mWindowDecorationViewModel.onTaskVanished(taskInfo);
        if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
            mWindowDecorationViewModel.destroyWindowDecoration(taskInfo);
        }
+1 −1
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
                taskInfo.taskId);
        mTasks.remove(taskInfo.taskId);

        mWindowDecorViewModelOptional.ifPresent(v -> v.onTaskVanished(taskInfo));
        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
        if (mWindowDecorViewModelOptional.isPresent()) {
            mWindowDecorViewModelOptional.get().destroyWindowDecoration(taskInfo);
+1 −0
Original line number Diff line number Diff line
@@ -260,6 +260,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskVanished: task=%d", taskInfo.taskId);
        final int taskId = taskInfo.taskId;
        mWindowDecorViewModel.ifPresent(vm -> vm.onTaskVanished(taskInfo));
        if (mRootTaskInfo.taskId == taskId) {
            mCallbacks.onRootTaskVanished();
            mRootTaskInfo = null;
+15 −0
Original line number Diff line number Diff line
@@ -118,6 +118,21 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        setupCaptionColor(taskInfo, decoration);
    }

    @Override
    public void onTaskVanished(RunningTaskInfo taskInfo) {
        // A task vanishing doesn't necessarily mean the task was closed, it could also mean its
        // windowing mode changed. We're only interested in closing tasks so checking whether
        // its info still exists in the task organizer is one way to disambiguate.
        final boolean closed = mTaskOrganizer.getRunningTaskInfo(taskInfo.taskId) == null;
        if (closed) {
            // Destroying the window decoration is usually handled when a TRANSIT_CLOSE transition
            // changes happen, but there are certain cases in which closing tasks aren't included
            // in transitions, such as when a non-visible task is closed. See b/296921167.
            // Destroy the decoration here in case the lack of transition missed it.
            destroyWindowDecoration(taskInfo);
        }
    }

    @Override
    public void onTaskChanging(
            RunningTaskInfo taskInfo,
+18 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;

import android.annotation.NonNull;
@@ -72,6 +73,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -308,6 +310,22 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        decoration.relayout(taskInfo);
    }

    @Override
    public void onTaskVanished(RunningTaskInfo taskInfo) {
        // A task vanishing doesn't necessarily mean the task was closed, it could also mean its
        // windowing mode changed. We're only interested in closing tasks so checking whether
        // its info still exists in the task organizer is one way to disambiguate.
        final boolean closed = mTaskOrganizer.getRunningTaskInfo(taskInfo.taskId) == null;
        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "Task Vanished: #%d closed=%b", taskInfo.taskId, closed);
        if (closed) {
            // Destroying the window decoration is usually handled when a TRANSIT_CLOSE transition
            // changes happen, but there are certain cases in which closing tasks aren't included
            // in transitions, such as when a non-visible task is closed. See b/296921167.
            // Destroy the decoration here in case the lack of transition missed it.
            destroyWindowDecoration(taskInfo);
        }
    }

    @Override
    public void onTaskChanging(
            RunningTaskInfo taskInfo,
Loading