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

Commit 28b9201e authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Make IME visiblity stable without unexpected hidden when setControl

2 reasons that may unexpectly calls hideMySoftInput from IME:

1) When requesting show IME on the activity, before receiving the
   control from server side, the null control might received from the
   relayoutWindow, if initially in consumer side didn't get the control
   yet, we should not hide the IME immediately to broke the on-going
   show request.

2) When ImeInsetsSourceConsumer#onWindowFocusGained, if we don't set
   mIsRequestedVisibleAwaitingControl as true if it has requested IME
   visible but not yet get control, it also could possble mistakenly
   hide IME when ImeInsetsSourceConsumer#setControl.

As the result, we should prevent both case with

1) add returned value for InsetsSourceConsumer#setControl to see whether
   the control has changed from the server, if the control didn't
   change like receiving a duplicated null control callback,
   then in ImeInsetsConsumer didn't have to do anything.
2) set mIsRequestedVisibleAwaitingControl as true when receiving
   onWindowFocusGained and the host is waiting the control to make
   IME visibility reliable.

Bug: 227142436
Bug: 204524304
Test: atest FlickerTests:LaunchAppShowImeAndDialogThemeAppTest
        --rerun-until-failure 10

Change-Id: If4b09f5b52bc96cf3429aaa912961f3ac4e326f2
parent 57edb1f7
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -65,6 +65,9 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    public void onWindowFocusGained(boolean hasViewFocus) {
        super.onWindowFocusGained(hasViewFocus);
        getImm().registerImeConsumer(this);
        if (isRequestedVisible() && getControl() == null) {
            mIsRequestedVisibleAwaitingControl = true;
        }
    }

    @Override
@@ -149,14 +152,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    }

    @Override
    public void setControl(@Nullable InsetsSourceControl control, int[] showTypes,
    public boolean setControl(@Nullable InsetsSourceControl control, int[] showTypes,
            int[] hideTypes) {
        super.setControl(control, showTypes, hideTypes);
        // TODO(b/204524304): clean-up how to deal with the timing issues of hiding IME:
        //  1) Already requested show IME, in the meantime of WM callback the control but got null
        //  control when relayout comes first
        //  2) Make sure no regression on some implicit request IME visibility calls (e.g.
        //  toggleSoftInput)
        if (!super.setControl(control, showTypes, hideTypes)) {
            return false;
        }
        if (control == null && !mIsRequestedVisibleAwaitingControl) {
            hide();
            removeSurface();
@@ -164,6 +164,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
        if (control != null) {
            mIsRequestedVisibleAwaitingControl = false;
        }
        return true;
    }

    @Override
+4 −2
Original line number Diff line number Diff line
@@ -121,8 +121,9 @@ public class InsetsSourceConsumer {
     *                  animation should be run after setting the control.
     * @param hideTypes An integer array with a single entry that determines which types a hide
     *                  animation should be run after setting the control.
     * @return Whether the control has changed from the server
     */
    public void setControl(@Nullable InsetsSourceControl control,
    public boolean setControl(@Nullable InsetsSourceControl control,
            @InsetsType int[] showTypes, @InsetsType int[] hideTypes) {
        if (mType == ITYPE_IME) {
            ImeTracing.getInstance().triggerClientDump("InsetsSourceConsumer#setControl",
@@ -133,7 +134,7 @@ public class InsetsSourceConsumer {
                mSourceControl.release(SurfaceControl::release);
                mSourceControl = control;
            }
            return;
            return false;
        }
        SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null;

@@ -198,6 +199,7 @@ public class InsetsSourceConsumer {
        if (lastControl != null) {
            lastControl.release(SurfaceControl::release);
        }
        return true;
    }

    @VisibleForTesting