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

Commit 4d3e6b2f authored by Felix Stern's avatar Felix Stern Committed by Android (Google) Code Review
Browse files

Merge "Update the server visibility before layout" into main

parents 2167e20c e729560d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ public class ImePerfTest extends ImePerfTestBase
            "IMMS.applyImeVisibility",
            "applyPostLayoutPolicy",
            "applyWindowSurfaceChanges",
            "ISC.onPreLayout",
            "ISC.onPostLayout"
    };

+6 −0
Original line number Diff line number Diff line
@@ -219,3 +219,9 @@ flag {
  bug: "139872425"
}

flag {
  name: "set_server_visibility_onprelayout"
  namespace: "input_method"
  description: "Set server visibility before performLayout to avoid additional window layout traversal."
  bug: "427863960"
}
+4 −0
Original line number Diff line number Diff line
@@ -5072,6 +5072,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            setLayoutNeeded();
        }

        if (android.view.inputmethod.Flags.setServerVisibilityOnprelayout()) {
            mInsetsStateController.onPreLayout();
        }

        // Perform a layout, if needed.
        performLayout(true /* initial */, false /* updateInputWindows */);
        pendingLayoutChanges = 0;
+46 −13
Original line number Diff line number Diff line
@@ -71,6 +71,12 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
     */
    private boolean mServerVisible;

    /**
     * The server visibility of the source provider's window before the latest
     * {@link #onPreLayout} call.
     */
    private boolean mServerVisiblePreLayout;

    /**
     * When the IME is not ready, it has givenInsetsPending. However, this could happen again,
     * after it became serverVisible. This flag indicates is used to determine if it is
@@ -92,18 +98,31 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
    }

    @Override
    void onPostLayout() {
    void onPreLayout() {
        if (!android.view.inputmethod.Flags.setServerVisibilityOnprelayout()) {
            return;
        }
        mServerVisiblePreLayout = mServerVisible;
        super.onPreLayout();

        mLastDrawn = mWin != null && mWin.isDrawn();
    }

    @Override
    boolean onPostLayout() {
        final boolean wasSourceVisible = mSource.isVisible();
        super.onPostLayout();
        if (wasSourceVisible != mSource.isVisible()) {
        final boolean controlDispatched = super.onPostLayout();
        if (!android.view.inputmethod.Flags.setServerVisibilityOnprelayout()
                && wasSourceVisible != mSource.isVisible()) {
            // TODO(b/427863960): Remove this and set the server visibility in onPreLayout
            // If the IME visibility has changed, a traversal needs to apply.
            mDisplayContent.setLayoutNeeded();
        }

        final boolean givenInsetsPending = mWin != null && mWin.mGivenInsetsPending;
        if (!android.view.inputmethod.Flags.setServerVisibilityOnprelayout()) {
            mLastDrawn = mWin != null && mWin.isDrawn();

        }
        // isLeashReadyForDispatching (used to dispatch the leash of the control) is
        // depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here
        // again, so that the control with leash can be eventually dispatched
@@ -115,10 +134,14 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
            mGivenInsetsReady = true;
            ImeTracker.forLogging().onProgress(mStatsToken,
                    ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
            if (!controlDispatched) {
                mStateController.notifyControlChanged(mControlTarget, this);
            }
            setImeShowing(true);
        } else if (wasSourceVisible && isServerVisible() && mGivenInsetsReady
                && givenInsetsPending) {
            return true;
        } else if (((!android.view.inputmethod.Flags.setServerVisibilityOnprelayout()
                && wasSourceVisible) || mServerVisiblePreLayout) && isServerVisible()
                && mGivenInsetsReady && givenInsetsPending) {
            // If the server visibility didn't change (still visible), and mGivenInsetsReady
            // is set, we won't call into notifyControlChanged. Therefore, we can reset the
            // statsToken, if available.
@@ -127,12 +150,22 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
            ImeTracker.forLogging().onCancelled(mStatsToken,
                    ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
            mStatsToken = null;
        } else if (isImeShowing() && !isServerVisible()) {
        } else if (!isServerVisible()) {
            if (isImeShowing()) {
                ProtoLog.d(WM_DEBUG_IME,
                        "onPostLayout: setImeShowing(false) was: true, controlTarget=%s",
                        mControlTarget);
                setImeShowing(false);
            }
            if (android.view.inputmethod.Flags.setServerVisibilityOnprelayout()
                    && mControlTarget != null && mServerVisiblePreLayout && !controlDispatched) {
                // If the server visibility changed (not visible anymore), we need to dispatch
                // the control.
                mStateController.notifyControlChanged(mControlTarget, this);
                return true;
            }
        }
        return controlDispatched;
    }

    @Nullable
+34 −9
Original line number Diff line number Diff line
@@ -362,28 +362,53 @@ class InsetsSourceProvider {
    }

    /**
     * Called when a layout pass has occurred.
     * Called before a layout pass will occur.
     */
    void onPostLayout() {
    void onPreLayout() {
        if (!android.view.inputmethod.Flags.setServerVisibilityOnprelayout()) {
            return;
        }
        if (mWin == null) {
            return;
        }
        setServerVisible(isSurfaceVisible());
    }

    /**
     * Called after a layout pass has occurred.
     *
     * @return {@code true} if {@link InsetsStateController#notifyControlChanged} was called or
     * was scheduled to be called within this method, else {@code false}.
     */
    boolean onPostLayout() {
        if (mWin == null) {
            return false;
        }
        final boolean serverVisibleChanged;
        if (!android.view.inputmethod.Flags.setServerVisibilityOnprelayout()) {
            final boolean isServerVisible = isSurfaceVisible();

        final boolean serverVisibleChanged = mServerVisible != isServerVisible;
            serverVisibleChanged = mServerVisible != isServerVisible;
            setServerVisible(isServerVisible);
        } else {
            serverVisibleChanged = false;
        }
        if (mControl != null && mControlTarget != null) {
            final boolean positionChanged = updateInsetsControlPosition(mWin);
            if (!(positionChanged || mHasPendingPosition)
            if (positionChanged || mHasPendingPosition) {
                return true;
            }
            // The insets hint would be updated while changing the position. Here updates it
                    // for the possible change of the bounds or the server visibility.
                    && (updateInsetsHint(mControl) || serverVisibleChanged)) {
            // for the possible change of the bounds.
            if (updateInsetsHint(mControl) || serverVisibleChanged) {
                // Only call notifyControlChanged here when the position hasn't been or won't be
                // changed. Otherwise, it has been called or scheduled to be called during
                // updateInsetsControlPosition.
                mStateController.notifyControlChanged(mControlTarget, this);
                return true;
            }
        }
        return false;
    }

    /**
Loading