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

Commit 458d2362 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adding IME drawing status to ImeInsetsSourceProvider" into main

parents e548b6f2 bfc916e4
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -82,6 +82,13 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
     */
    private boolean mGivenInsetsReady = false;

    /**
     * The last state of the windowContainer. This is used to reset server visibility, in case of
     * the IME (temporarily) redrawing  (e.g. during a rotation), to dispatch the control with
     * leash again after it has finished drawing.
     */
    private boolean mLastDrawn = false;

    ImeInsetsSourceProvider(@NonNull InsetsSource source,
            @NonNull InsetsStateController stateController,
            @NonNull DisplayContent displayContent) {
@@ -97,6 +104,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
            final WindowState ws =
                    mWindowContainer != null ? mWindowContainer.asWindowState() : null;
            final boolean givenInsetsPending = ws != null && ws.mGivenInsetsPending;
            mLastDrawn = ws != null && ws.isDrawn();

            // isLeashReadyForDispatching (used to dispatch the leash of the control) is
            // depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here
@@ -158,6 +166,35 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
        }
    }

    /**
     * This is used to determine the desired serverVisibility state. For the IME, just having a
     * window state that would be visible by policy is not enough.
     */
    @Override
    protected boolean isSurfaceVisible() {
        final boolean isSurfaceVisible = super.isSurfaceVisible();
        if (android.view.inputmethod.Flags.refactorInsetsController()) {
            final WindowState windowState = mWindowContainer.asWindowState();
            if (mControl != null && windowState != null) {
                final boolean isDrawn = windowState.isDrawn();
                if (!isServerVisible() && isSurfaceVisible) {
                    // In case the IME becomes visible, we need to check if it is already drawn and
                    // does not have given insets pending. If it's not yet drawn, we do not set
                    // server visibility
                    return isDrawn && !windowState.mGivenInsetsPending;
                } else if (mLastDrawn && !isDrawn) {
                    // If the IME was drawn before, but is not drawn anymore, we need to reset
                    // server visibility, which will also reset {@link
                    // ImeInsetsSourceProvider#mGivenInsetsReady}. Otherwise, the new control
                    // with leash won't be dispatched after the surface has redrawn.
                    return false;
                }
            }
        }
        return isSurfaceVisible;
    }


    @Nullable
    @Override
    InsetsSourceControl getControl(InsetsControlTarget target) {
@@ -779,6 +816,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
        pw.print(prefix);
        pw.print("mImeShowing=");
        pw.print(mImeShowing);
        pw.print(" mLastDrawn=");
        pw.print(mLastDrawn);
        if (mImeRequester != null) {
            pw.print(prefix);
            pw.print("showImePostLayout pending for mImeRequester=");
+12 −13
Original line number Diff line number Diff line
@@ -175,6 +175,16 @@ class InsetsSourceProvider {
        return mControllable;
    }

    /**
     * @return Whether the current window container has a visible surface.
     */
    protected boolean isSurfaceVisible() {
        final WindowState windowState = mWindowContainer.asWindowState();
        return windowState != null
                ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy()
                : mWindowContainer.isVisibleRequested();
    }

    /**
     * Updates the window container that currently backs this source.
     *
@@ -368,20 +378,9 @@ class InsetsSourceProvider {
        if (mWindowContainer == null) {
            return;
        }
        WindowState windowState = mWindowContainer.asWindowState();
        boolean isServerVisible = windowState != null
                ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy()
                : mWindowContainer.isVisibleRequested();
        final WindowState windowState = mWindowContainer.asWindowState();
        final boolean isServerVisible = isSurfaceVisible();

        if (android.view.inputmethod.Flags.refactorInsetsController()) {
            if (mControl != null && mControl.getType() == WindowInsets.Type.ime() && !mServerVisible
                    && isServerVisible && windowState != null) {
                // in case the IME becomes visible, we need to check if it is already drawn and
                // does not have given insets pending. If it's not yet drawn, we do not set
                // server visibility
                isServerVisible = windowState.isDrawn() && !windowState.mGivenInsetsPending;
            }
        }
        final boolean serverVisibleChanged = mServerVisible != isServerVisible;
        setServerVisible(isServerVisible);
        if (mControl != null && mControlTarget != null) {
+32 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;

import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
import static com.android.server.wm.WindowStateAnimator.NO_SURFACE;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -244,4 +247,33 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase {
        verify(displayWindowInsetsController, times(1)).setImeInputTargetRequestedVisibility(
                eq(true), any());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
    public void testOnPostLayout_resetServerVisibilityWhenImeIsNotDrawn() {
        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
        final WindowState inputTarget = newWindowBuilder("app", TYPE_APPLICATION).build();
        makeWindowVisibleAndDrawn(ime);
        mImeProvider.setWindowContainer(ime, null, null);
        mImeProvider.setServerVisible(true);
        mImeProvider.setClientVisible(true);
        mImeProvider.updateVisibility();
        mImeProvider.updateControlForTarget(inputTarget, true /* force */, null /* statsToken */);

        // Calling onPostLayout, as the drawn state is initially false.
        mImeProvider.onPostLayout();
        assertTrue(mImeProvider.isSurfaceVisible());

        // Reset window's drawn state
        ime.mWinAnimator.mDrawState = NO_SURFACE;
        mImeProvider.onPostLayout();
        assertFalse(mImeProvider.isServerVisible());
        assertFalse(mImeProvider.isSurfaceVisible());

        // Set it back to drawn
        ime.mWinAnimator.mDrawState = HAS_DRAWN;
        mImeProvider.onPostLayout();
        assertTrue(mImeProvider.isServerVisible());
        assertTrue(mImeProvider.isSurfaceVisible());
    }
}