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

Commit 8b1ae4a3 authored by Ben Lin's avatar Ben Lin
Browse files

Re-parent decor SurfaceControl to task's if detached.

In cases where the app process dies (e.g. crashes, explicitly killed,
etc.), it is possible that WindowDecorations, given they are part of
Shell process, will persist in limbo attached to a dead task leash. On a
new task launch with a new task SurfaceControl, since
WindowDecorViewModel still holds a reference to the old decoration (we
never get a onTaskClosed transition), it acts as if nothing is wrong and
updates the existing decoration accordingly, not knowing it is no longer
visible to the user.

This does a check when we get shell transition call and check its
taskSurface, and make sure it matches the one that the decoration has.
If it is no longer the same, we then reparent the decoration's
SurfaceControl to the new taskSurface.

Bug: 435090772
Test: Manual. Crash an app explicitly and then relaunch it, and see
window controls still showing.
Flag: EXEMPT bugfix

Change-Id: Iec1fdcfeec2fbaa14c6b8208ad8a095378787146
parent f4243b2d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -257,7 +257,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
            decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                    false /* setTaskCropAndPosition */,
                    mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion,
                    /* inSyncWithTransition= */ true);
                    /* inSyncWithTransition= */ true, taskSurface);
        }
    }

@@ -272,7 +272,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
        decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                false /* setTaskCropAndPosition */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion,
                /* inSyncWithTransition= */ true);
                /* inSyncWithTransition= */ true, /* taskSurface */ null);
    }

    @Override
@@ -372,7 +372,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
        windowDecoration.relayout(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */, false /* setTaskCropAndPosition */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion,
                /* inSyncWithTransition= */ true);
                /* inSyncWithTransition= */ true, taskSurface);
    }

    private class CaptionTouchEventListener implements
+3 −1
Original line number Diff line number Diff line
@@ -307,6 +307,7 @@ constructor(
            hasGlobalFocus,
            displayExclusionRegion,
            inSyncWithTransition = false,
            taskSurface,
        )
        if (!applyTransactionOnDraw) {
            t.apply()
@@ -323,6 +324,7 @@ constructor(
        hasGlobalFocus: Boolean,
        displayExclusionRegion: Region,
        inSyncWithTransition: Boolean,
        taskSurface: SurfaceControl?,
    ) =
        traceSection("DefaultWindowDecoration#relayout") {
            if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue) {
@@ -356,7 +358,7 @@ constructor(
                )

            val wct = windowContainerTransactionSupplier.invoke()
            relayout(relayoutParams, startT, finishT, wct)
            relayout(relayoutParams, startT, finishT, wct, taskSurface)

            // After this line, taskInfo  is up-to-date and should be used instead of taskInfo
            if (!wct.isEmpty) {
+3 −3
Original line number Diff line number Diff line
@@ -658,7 +658,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                    false /* shouldSetTaskPositionAndCrop */,
                    mFocusTransitionObserver.hasGlobalFocus(taskInfo),
                    mGestureExclusionTracker.getExclusionRegion(taskInfo.displayId),
                    /* inSyncWithTransition= */ true);
                    /* inSyncWithTransition= */ true, taskSurface);
        }
    }

@@ -733,7 +733,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                false /* shouldSetTaskPositionAndCrop */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo),
                mGestureExclusionTracker.getExclusionRegion(taskInfo.displayId),
                /* inSyncWithTransition= */ true);
                /* inSyncWithTransition= */ true, /* taskSurface */ null);
    }

    @Override
@@ -2162,7 +2162,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo),
                mGestureExclusionTracker.getExclusionRegion(taskInfo.displayId),
                /* inSyncWithTransition= */ true);
                /* inSyncWithTransition= */ true, taskSurface);
        if (!DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) {
            incrementEventReceiverTasks(taskInfo.displayId);
        }
+19 −2
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ abstract class WindowDecoration2<T>(
    private val context: Context,
    private val displayController: DisplayController,
    taskSurface: SurfaceControl,
    surfaceControlSupplier: () -> SurfaceControl,
    private val surfaceControlSupplier: () -> SurfaceControl,
    private val taskOrganizer: ShellTaskOrganizer,
    @ShellMainThread private val handler: Handler,
    private val surfaceControlBuilderSupplier: () -> SurfaceControl.Builder = {
@@ -105,7 +105,9 @@ abstract class WindowDecoration2<T>(
            }
        }
    /** The surface control of the task that owns this decoration. */
    val taskSurface = cloneSurfaceControl(taskSurface, surfaceControlSupplier)
    var taskSurface = cloneSurfaceControl(taskSurface, surfaceControlSupplier)
        private set

    protected var decorationContainerSurface: SurfaceControl? = null
    /** Sets the [TaskDragResizer] which allows task to be drag-resized. */
    var taskDragResizer: TaskDragResizer? = null
@@ -150,6 +152,7 @@ abstract class WindowDecoration2<T>(
        startT: SurfaceControl.Transaction,
        finishT: SurfaceControl.Transaction,
        wct: WindowContainerTransaction,
        newTaskSurface: SurfaceControl?,
    ): RelayoutResult<T>? =
        traceSection(
            traceTag = Trace.TRACE_TAG_WINDOW_MANAGER,
@@ -159,6 +162,20 @@ abstract class WindowDecoration2<T>(
            hasGlobalFocus = params.hasGlobalFocus
            exclusionRegion.set(params.displayExclusionRegion)

            if (
                decorationContainerSurface != null &&
                    newTaskSurface != null &&
                    !newTaskSurface.isSameSurface(taskSurface)
            ) {
                val containerSurface =
                    checkNotNull(decorationContainerSurface) {
                        "expected non-null decoration container surface"
                    }
                taskSurface.release()
                taskSurface = cloneSurfaceControl(newTaskSurface, surfaceControlSupplier)
                startT.reparent(containerSurface, taskSurface)
            }

            if (!taskInfo.isVisible) {
                releaseViews(wct)
                if (params.setTaskVisibilityPositionAndCrop) {
+2 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ private constructor(
        hasGlobalFocus: Boolean,
        displayExclusionRegion: Region,
        inSyncWithTransition: Boolean,
        taskSurface: SurfaceControl?,
    ) =
        when {
            defaultWindowDecor != null -> {
@@ -223,6 +224,7 @@ private constructor(
                        hasGlobalFocus,
                        displayExclusionRegion,
                        inSyncWithTransition,
                        taskSurface,
                    )
            }