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

Commit b50ba0c4 authored by Qijing Yao's avatar Qijing Yao
Browse files

Unregister DisplayWindowListener when window closed

To support drag across multi-displays, we added
MultiDisplayVeiledResizeTaskPositioner as an OnDisplaysChangedListener
to DisplayController. However, the listener was never unregistered,
and since a new taskPositioner is created for each window, this
resulted in a memory leak.

This change addresses the issue by:
* Adding a `close()` method to the `TaskDragResizer` interface and its
implementations. For `MultiDisplayVeiledResizeTaskPositioner`, it
removes the listener from `DisplayController`. For other
implementations, it's a no-op.
* Calling `TaskDragResizer.close()` in `WindowDecoration#close()`.

Bug: 399076683
Test: atest; check heap dump to confirm the memory leak is resolved
Flag: com.android.window.flags.enable_connected_displays_window_drag

Change-Id: I14f0c3d04385c06899f846ceaa1962b024cdc62e
parent 4f06c68f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -173,6 +173,9 @@ class FluidResizeTaskPositioner implements TaskPositioner, Transitions.Transitio
        return new Rect(mRepositionTaskBounds);
    }

    @Override
    public void close() {}

    private boolean isResizing() {
        return (mCtrlType & CTRL_TYPE_TOP) != 0 || (mCtrlType & CTRL_TYPE_BOTTOM) != 0
                || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0;
+4 −0
Original line number Diff line number Diff line
@@ -294,6 +294,10 @@ class MultiDisplayVeiledResizeTaskPositioner(
        return Rect(repositionTaskBounds)
    }

    override fun close() {
        displayController.removeDisplayWindowListener(this)
    }

    private fun resetVeilIfVisible() {
        if (isResizingOrAnimatingResize) {
            desktopWindowDecoration.hideResizeVeil()
+6 −0
Original line number Diff line number Diff line
@@ -41,4 +41,10 @@ public interface TaskDragResizer {
     */
    void removeDragEventListener(
            DragPositioningCallbackUtility.DragEventListener dragEventListener);

    /**
     * Releases any resources associated with this TaskDragResizer. This should be called when the
     * associated window is closed.
     */
    void close();
}
+3 −0
Original line number Diff line number Diff line
@@ -205,6 +205,9 @@ public class VeiledResizeTaskPositioner implements TaskPositioner, Transitions.T
        return new Rect(mRepositionTaskBounds);
    }

    @Override
    public void close() {}

    private boolean isResizing() {
        return (mCtrlType & CTRL_TYPE_TOP) != 0 || (mCtrlType & CTRL_TYPE_BOTTOM) != 0
                || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0;
+3 −0
Original line number Diff line number Diff line
@@ -695,6 +695,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
    public void close() {
        Trace.beginSection("WindowDecoration#close");
        mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener);
        if (mTaskDragResizer != null) {
            mTaskDragResizer.close();
        }
        final WindowContainerTransaction wct = mWindowContainerTransactionSupplier.get();
        releaseViews(wct);
        mTaskOrganizer.applyTransaction(wct);
Loading