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

Commit a18650be authored by Adrian Roos's avatar Adrian Roos
Browse files

DisplayImeController: fix out-of-sync IME visibility

Fixes an issue where the DisplayImeController would disagree with
the InputMethodManagerService about the visibility of the IME.

Currently, the Insets component is supposed to execute the
visibility as dictated by IMMS; however, when the DisplayImeController
became the control target, previously it would just apply the IME
visibility that was last requested of it - regardless of the
changes to it that may have happened while it was not the control
target.

Eventually, IME visibility should be driven by the requested IME
inset visibility of the focused window, instead of the separate
dispatch we have now from IMMS.

Bug: 167780081
Test: atest DisplayImeControllerTest ImeInsetsSourceProviderTest
Change-Id: I1f140af6bcccbcbe6efb2fde9a789ac4c7bd127f
parent 29f0617c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
@@ -204,6 +203,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                    return;
                }

                mImeShowing = insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME);

                final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
                final Rect newFrame = newSource.getFrame();
                final Rect oldFrame = mInsetsState.getSource(InsetsState.ITYPE_IME).getFrame();
+22 −7
Original line number Diff line number Diff line
@@ -20,12 +20,15 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.Surface.ROTATION_0;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.graphics.Point;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.SurfaceControl;
@@ -68,19 +71,31 @@ public class DisplayImeControllerTest {
    @Test
    public void reappliesVisibilityToChangedLeash() {
        verifyZeroInteractions(mT);
        mPerDisplay.mImeShowing = true;

        mPerDisplay.mImeShowing = false;
        mPerDisplay.insetsControlChanged(new InsetsState(), new InsetsSourceControl[] {
                new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
        });
        mPerDisplay.insetsControlChanged(insetsStateWithIme(false), insetsSourceControl());

        assertFalse(mPerDisplay.mImeShowing);
        verify(mT).hide(any());

        mPerDisplay.mImeShowing = true;
        mPerDisplay.insetsControlChanged(new InsetsState(), new InsetsSourceControl[] {
                new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
        });
        mPerDisplay.insetsControlChanged(insetsStateWithIme(true), insetsSourceControl());

        assertTrue(mPerDisplay.mImeShowing);
        verify(mT).show(any());
    }

    private InsetsSourceControl[] insetsSourceControl() {
        return new InsetsSourceControl[]{
                new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
        };
    }

    private InsetsState insetsStateWithIme(boolean visible) {
        InsetsState state = new InsetsState();
        state.addSource(new InsetsSource(ITYPE_IME));
        state.setSourceVisible(ITYPE_IME, visible);
        return state;
    }

}
+3 −0
Original line number Diff line number Diff line
@@ -5657,6 +5657,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

        @Override
        public boolean getRequestedVisibility(@InternalInsetsType int type) {
            if (type == ITYPE_IME) {
                return getInsetsStateController().getImeSourceProvider().isImeShowing();
            }
            return mRequestedInsetsState.getSourceOrDefaultVisibility(type);
        }

+23 −3
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
    private InsetsControlTarget mImeTargetFromIme;
    private Runnable mShowImeRunner;
    private boolean mIsImeLayoutDrawn;
    private boolean mImeShowing;

    ImeInsetsSourceProvider(InsetsSource source,
            InsetsStateController stateController, DisplayContent displayContent) {
@@ -81,6 +82,7 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {

                ProtoLog.i(WM_DEBUG_IME, "call showInsets(ime) on %s",
                        target.getWindow() != null ? target.getWindow().getName() : "");
                setImeShowing(true);
                target.showInsets(WindowInsets.Type.ime(), true /* fromIme */);
                Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "WMS.showImePostLayout", 0);
                if (target != mImeTargetFromIme && mImeTargetFromIme != null) {
@@ -155,12 +157,14 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
    @Override
    public void dump(PrintWriter pw, String prefix) {
        super.dump(pw, prefix);
        if (mImeTargetFromIme != null) {
        pw.print(prefix);
        pw.print("mImeShowing=");
        pw.print(mImeShowing);
        if (mImeTargetFromIme != null) {
            pw.print(" showImePostLayout pending for mImeTargetFromIme=");
            pw.print(mImeTargetFromIme);
            pw.println();
        }
        pw.println();
    }

    @Override
@@ -173,4 +177,20 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
        proto.write(IS_IME_LAYOUT_DRAWN, mIsImeLayoutDrawn);
        proto.end(token);
    }

    /**
     * Sets whether the IME is currently supposed to be showing according to
     * InputMethodManagerService.
     */
    public void setImeShowing(boolean imeShowing) {
        mImeShowing = imeShowing;
    }

    /**
     * Returns whether the IME is currently supposed to be showing according to
     * InputMethodManagerService.
     */
    public boolean isImeShowing() {
        return mImeShowing;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -328,7 +328,7 @@ class InsetsSourceProvider {
        final Point surfacePosition = getWindowFrameSurfacePosition();
        mAdapter = new ControlAdapter(surfacePosition);
        if (getSource().getType() == ITYPE_IME) {
            setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
            setClientVisible(target.getRequestedVisibility(mSource.getType()));
        }
        final Transaction t = mDisplayContent.getPendingTransaction();
        mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */,
Loading