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

Commit 941ad3a5 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Decouple display area from windowing layer

FEATURE_WINDOWED_MAGNIFICATION was a necessary feature of a display.
Because screen level surface animation needs a layer containing
all non-overlay window for reparenting leash. But that seems to
restrict the customizability of non-default display.

This change makes the feature optional by creating an additional
layer if the feature doesn't exist. So a display can create without
any display area features.

Also remove some unused fields.

Bug: 175179353
Test: DisplayContentTests#testValidWindowingLayer
Change-Id: I5c8712e7650a51fc57ea2dc5c60176d7dcafe1d1
parent a0334be8
Loading
Loading
Loading
Loading
+28 −24
Original line number Diff line number Diff line
@@ -283,6 +283,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     */
    private SurfaceControl mOverlayLayer;

    /**
     * The direct child layer of the display to put all non-overlay windows. This is also used for
     * screen rotation animation so that there is a parent layer to put the animation leash.
     */
    private final SurfaceControl mWindowingLayer;

    // Contains all IME window containers. Note that the z-ordering of the IME windows will depend
    // on the IME target. We mainly have this container grouping so we can keep track of all the IME
    // window containers together and move them in-sync if/when needed. We use a subclass of
@@ -294,7 +300,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    final DisplayAreaPolicy mDisplayAreaPolicy;

    private WindowState mTmpWindow;
    private WindowState mTmpWindow2;
    private boolean mUpdateImeTarget;
    private boolean mTmpInitial;
    private int mMaxUiWidth;
@@ -459,10 +464,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    private final ApplySurfaceChangesTransactionState mTmpApplySurfaceChangesTransactionState =
            new ApplySurfaceChangesTransactionState();

    // True if this display is in the process of being removed. Used to determine if the removal of
    // the display's direct children should be allowed.
    private boolean mRemovingDisplay = false;

    // {@code false} if this display is in the processing of being created.
    private boolean mDisplayReady = false;

@@ -1023,6 +1024,27 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                .setContainerLayer()
                .setCallsite("DisplayContent");
        mSurfaceControl = b.setName("Root").setContainerLayer().build();

        // Setup the policy and build the display area hierarchy.
        mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
                mWmService, this /* content */, this /* root */, mImeWindowsContainers);

        final List<DisplayArea<? extends WindowContainer>> areas =
                mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
        final DisplayArea<?> area = areas.size() == 1 ? areas.get(0) : null;
        if (area != null && area.getParent() == this) {
            // The windowed magnification area should contain all non-overlay windows, so just use
            // it as the windowing layer.
            mWindowingLayer = area.mSurfaceControl;
        } else {
            // Need an additional layer for screen level animation, so move the layer containing
            // the windows to the new root.
            mWindowingLayer = mSurfaceControl;
            mSurfaceControl = b.setName("RootWrapper").build();
            getPendingTransaction().reparent(mWindowingLayer, mSurfaceControl)
                    .show(mWindowingLayer);
        }

        mOverlayLayer = b.setName("Display Overlays").setParent(mSurfaceControl).build();

        getPendingTransaction()
@@ -1033,10 +1055,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                .show(mOverlayLayer);
        getPendingTransaction().apply();

        // Setup the policy and build the display area hierarchy.
        mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
                mWmService, this /* content */, this /* root */, mImeWindowsContainers);

        // Sets the display content for the children.
        onDisplayChanged(this);

@@ -2796,7 +2814,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    @Override
    void removeImmediately() {
        mRemovingDisplay = true;
        mDeferredRemoval = false;
        try {
            if (mParentWindow != null) {
@@ -2820,7 +2837,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
        } finally {
            mDisplayReady = false;
            mRemovingDisplay = false;
        }

        // Apply the pending transaction here since we may not be able to reach the DisplayContent
@@ -4190,7 +4206,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

        // Used to indicate that we have processed the dream window and all additional attached
        // windows are behind it.
        mTmpWindow2 = mTmpWindow;
        mTmpWindow = null;

        // Now perform layout of attached windows, which usually depend on the position of the
@@ -4860,19 +4875,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }, false /* traverseTopToBottom */);
    }

    private DisplayArea getWindowContainers() {
        List<DisplayArea<? extends WindowContainer>> windowContainers =
                mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
        if (windowContainers.size() != 1) {
            throw new IllegalStateException("There should be only one DisplayArea for "
                    + "FEATURE_WINDOWED_MAGNIFICATION");
        }
        return windowContainers.get(0);
    }

    @VisibleForTesting
    SurfaceControl getWindowingLayer() {
        return getWindowContainers().getSurfaceControl();
        return mWindowingLayer;
    }

    DisplayArea.Tokens getImeContainer() {
+18 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
@@ -106,6 +107,7 @@ import android.view.IWindowManager;
import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;

@@ -1533,6 +1535,22 @@ public class DisplayContentTests extends WindowTestsBase {
        assertNull(taskDisplayArea.getOrCreateRootHomeTask());
    }

    @Test
    public void testValidWindowingLayer() {
        final SurfaceControl windowingLayer = mDisplayContent.getWindowingLayer();
        assertNotNull(windowingLayer);

        final List<DisplayArea<?>> windowedMagnificationAreas =
                mDisplayContent.mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
        if (windowedMagnificationAreas != null) {
            assertEquals("There should be only one DisplayArea for FEATURE_WINDOWED_MAGNIFICATION",
                    1, windowedMagnificationAreas.size());
            assertEquals(windowedMagnificationAreas.get(0).mSurfaceControl, windowingLayer);
        } else {
            assertNotEquals(mDisplayContent.mSurfaceControl, windowingLayer);
        }
    }

    @Test
    public void testFindScrollCaptureTargetWindow_behindWindow() {
        DisplayContent display = createNewDisplay();