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

Commit 07d9444e authored by Tiger Huang's avatar Tiger Huang
Browse files

Push the frame to InsetsSourceProvider

This CL stops InsetsSourceProvider from reading the frame from the
window. Instead, the caller sets the frame via #updateSourceFrame.

When the window layout is moved to the client side, when the rotation is
changed, we need to dispatch the InsetsState computed from the new
rotation to all the clients. At this moment, the window frames of insets
source windows are not up-to-date yet, and we cannot use them to
generate insets sources. Instead, we pre-compute the window frames based
on the new rotation at the server side, and use them to update
InsetsState. In this way, the first InsetsState dispatched to the client
after rotation will be correct.

This CL also

- unbundles the calling order of setServerVisible and updateSourceFrame.
  The calling order won't affect the result.

- moves logic from DisplayPolicy#layoutWindowLw to WindowState#setFrames
  because we plan to remove layoutWindowLw in the future.

- removes redundant logs about layout. The log in
  WindowLayout#computeFrames can cover them all.

Bug: 161810301
Test: Perform fixed rotation, seamless rotation, and regular rotation
      and see if the layout of each window is expected.
Change-Id: Ie7845de2830cdbdfd0049b8eef5a5f0704f796e8
parent d7556376
Loading
Loading
Loading
Loading
+26 −24
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ import android.os.UserHandle;
import android.util.ArraySet;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
@@ -1151,9 +1152,8 @@ public class DisplayPolicy {
                            }
                        },

                        // For IME we use regular frame.
                        (displayFrames, windowContainer, inOutFrame) -> {
                            inOutFrame.set(win.getFrame());
                            // For IME, we don't modify the frame.
                        });

                mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
@@ -1488,9 +1488,30 @@ public class DisplayPolicy {
                    displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
                    displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
                    null /* attachedWindowFrame */, win.mGlobalScale,
                    sTmpClientFrames);
            controller.computeSimulatedState(win, displayFrames, sTmpClientFrames.frame);
                    null /* attachedWindowFrame */, win.mGlobalScale, sTmpClientFrames);
            final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
            final InsetsState state = displayFrames.mInsetsState;
            for (int index = sources.size() - 1; index >= 0; index--) {
                final int type = sources.keyAt(index);
                state.addSource(controller.getSourceProvider(type).createSimulatedSource(
                        displayFrames, sTmpClientFrames.frame));
            }
        }
    }

    // TODO(b/161810301): No one is calling this since we haven't moved window layout to the client.
    //                    When that happens, this should be called when the display rotation is
    //                    changed, so that we can dispatch the correct insets to all the clients
    //                    before the insets source windows report their frames to the server.
    void updateInsetsSourceFramesExceptIme(DisplayFrames displayFrames) {
        for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
            final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
            mWindowLayout.computeFrames(win.getLayoutingAttrs(displayFrames.mRotation),
                    displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
                    displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
                    null /* attachedWindowFrame */, win.mGlobalScale, sTmpClientFrames);
            win.updateSourceFrame(sTmpClientFrames.frame);
        }
    }

@@ -1519,10 +1540,6 @@ public class DisplayPolicy {
        displayFrames = win.getDisplayFrames(displayFrames);

        final WindowManager.LayoutParams attrs = win.getLayoutingAttrs(displayFrames.mRotation);
        final WindowFrames windowFrames = win.getWindowFrames();
        final Rect pf = windowFrames.mParentFrame;
        final Rect df = windowFrames.mDisplayFrame;
        final Rect f = windowFrames.mFrame;
        final Rect attachedWindowFrame = attached != null ? attached.getFrame() : null;

        // If this window has different LayoutParams for rotations, we cannot trust its requested
@@ -1531,25 +1548,10 @@ public class DisplayPolicy {
        final int requestedWidth = trustedSize ? win.mRequestedWidth : UNSPECIFIED_LENGTH;
        final int requestedHeight = trustedSize ? win.mRequestedHeight : UNSPECIFIED_LENGTH;

        sTmpLastParentFrame.set(pf);

        mWindowLayout.computeFrames(attrs, win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
                win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight,
                win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
                sTmpClientFrames);
        windowFrames.setParentFrameWasClippedByDisplayCutout(
                sTmpClientFrames.isParentFrameClippedByDisplayCutout);

        if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
                + ": sim=#" + Integer.toHexString(attrs.softInputMode)
                + " attach=" + attached + " type=" + attrs.type
                + " flags=" + ViewDebug.flagsToString(LayoutParams.class, "flags", attrs.flags)
                + " pf=" + pf.toShortString() + " df=" + df.toShortString()
                + " f=" + f.toShortString());

        if (!sTmpLastParentFrame.equals(pf)) {
            windowFrames.setContentChanged(true);
        }

        win.setFrames(sTmpClientFrames);
    }
+3 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static com.android.server.wm.WindowManagerService.H.UPDATE_MULTI_WINDOW_S

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.Trace;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsSource;
@@ -79,8 +80,8 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider
    }

    @Override
    void updateSourceFrame() {
        super.updateSourceFrame();
    void updateSourceFrame(Rect frame) {
        super.updateSourceFrame(frame);
        onSourceChanged();
    }

+26 −28
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ abstract class InsetsSourceProvider {
    private TriConsumer<DisplayFrames, WindowContainer, Rect> mImeFrameProvider;
    private final Rect mImeOverrideFrame = new Rect();
    private boolean mIsLeashReadyForDispatching;
    private final Rect mSourceFrame = new Rect();
    private final Rect mLastSourceFrame = new Rect();

    private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
@@ -183,8 +184,8 @@ abstract class InsetsSourceProvider {
        mImeFrameProvider = imeFrameProvider;
        if (windowContainer == null) {
            setServerVisible(false);
            mSource.setFrame(new Rect());
            mSource.setVisibleFrame(null);
            mSourceFrame.setEmpty();
        } else {
            mWindowContainer.getProvidedInsetsSources().put(mSource.getType(), mSource);
            if (mControllable) {
@@ -208,7 +209,7 @@ abstract class InsetsSourceProvider {
     * The source frame can affect the layout of other windows, so this should be called once the
     * window container gets laid out.
     */
    void updateSourceFrame() {
    void updateSourceFrame(Rect frame) {
        if (mWindowContainer == null) {
            return;
        }
@@ -230,39 +231,25 @@ abstract class InsetsSourceProvider {
            return;
        }

        if (win.mGivenInsetsPending) {
            // If the given insets are pending, they are not reliable for now. The source frame
            // should be updated after the new given insets are sent to window manager.
            return;
        }

        // Make sure we set the valid source frame only when server visible is true, because the
        // frame may not yet determined that server side doesn't think the window is ready to
        // visible. (i.e. No surface, pending insets that were given during layout, etc..)
        if (mServerVisible) {
            mTmpRect.set(win.getFrame());
        mSourceFrame.set(frame);
        if (mFrameProvider != null) {
            mFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
                        mWindowContainer, mTmpRect);
            } else {
                mTmpRect.inset(win.mGivenContentInsets);
            }
                    mWindowContainer, mSourceFrame);
        } else {
            mTmpRect.setEmpty();
            mSourceFrame.inset(win.mGivenContentInsets);
        }
        mSource.setFrame(mTmpRect);
        updateSourceFrameForServerVisibility();

        if (mImeFrameProvider != null) {
            mImeOverrideFrame.set(win.getFrame());
            mImeOverrideFrame.set(frame);
            mImeFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
                    mWindowContainer,
                    mImeOverrideFrame);
                    mWindowContainer, mImeOverrideFrame);
        }

        if (win.mGivenVisibleInsets.left != 0 || win.mGivenVisibleInsets.top != 0
                || win.mGivenVisibleInsets.right != 0
                || win.mGivenVisibleInsets.bottom != 0) {
            mTmpRect.set(win.getFrame());
            mTmpRect.set(frame);
            mTmpRect.inset(win.mGivenVisibleInsets);
            mSource.setVisibleFrame(mTmpRect);
        } else {
@@ -270,13 +257,24 @@ abstract class InsetsSourceProvider {
        }
    }

    private void updateSourceFrameForServerVisibility() {
        // Make sure we set the valid source frame only when server visible is true, because the
        // frame may not yet determined that server side doesn't think the window is ready to
        // visible. (i.e. No surface, pending insets that were given during layout, etc..)
        if (mServerVisible) {
            mSource.setFrame(mSourceFrame);
        } else {
            mSource.setFrame(0, 0, 0, 0);
        }
    }

    /** @return A new source computed by the specified window frame in the given display frames. */
    InsetsSource createSimulatedSource(DisplayFrames displayFrames, Rect winFrame) {
    InsetsSource createSimulatedSource(DisplayFrames displayFrames, Rect frame) {
        // Don't copy visible frame because it might not be calculated in the provided display
        // frames and it is not significant for this usage.
        final InsetsSource source = new InsetsSource(mSource.getType());
        source.setVisible(mSource.isVisible());
        mTmpRect.set(winFrame);
        mTmpRect.set(frame);
        if (mFrameProvider != null) {
            mFrameProvider.accept(displayFrames, mWindowContainer, mTmpRect);
        }
@@ -296,7 +294,6 @@ abstract class InsetsSourceProvider {
                ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy()
                : mWindowContainer.isVisibleRequested();
        setServerVisible(isServerVisible);
        updateSourceFrame();
        if (mControl != null) {
            boolean changed = false;
            final Point position = getWindowFrameSurfacePosition();
@@ -496,6 +493,7 @@ abstract class InsetsSourceProvider {
    @VisibleForTesting
    void setServerVisible(boolean serverVisible) {
        mServerVisible = serverVisible;
        updateSourceFrameForServerVisibility();
        updateVisibility();
    }

+0 −18
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -204,23 +203,6 @@ class InsetsStateController {
        }
    }

    /**
     * Computes insets state of the insets provider window in the display frames.
     *
     * @param win The owner window of insets provider.
     * @param displayFrames The display frames to create insets source.
     * @param winFrame The frame of the insets source window.
     */
    void computeSimulatedState(WindowState win, DisplayFrames displayFrames, Rect winFrame) {
        final InsetsState state = displayFrames.mInsetsState;
        for (int i = mProviders.size() - 1; i >= 0; i--) {
            final WindowContainerInsetsSourceProvider provider = mProviders.valueAt(i);
            if (provider.mWindowContainer == win) {
                state.addSource(provider.createSimulatedSource(displayFrames, winFrame));
            }
        }
    }

    boolean isFakeTarget(@InternalInsetsType int type, InsetsControlTarget target) {
        return mTypeFakeControlTargetMap.get(type) == target;
    }
+1 −0
Original line number Diff line number Diff line
@@ -2157,6 +2157,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        w.mGivenTouchableRegion.scale(w.mGlobalScale);
                    }
                    w.setDisplayLayoutNeeded();
                    w.updateSourceFrame(w.getFrame());
                    mWindowPlacerLocked.performSurfacePlacement();
                    w.getDisplayContent().getInputMonitor().updateInputWindowsLw(true);

Loading