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

Commit 66a05f47 authored by Tiger Huang's avatar Tiger Huang Committed by Android (Google) Code Review
Browse files

Merge "Fix the logic about notifyImeHidden and removeImeSurface"

parents 29c28e1d 1be63da3
Loading
Loading
Loading
Loading
+33 −35
Original line number Diff line number Diff line
@@ -17,10 +17,9 @@
package android.view;

import static android.os.Trace.TRACE_TAG_VIEW;
import static android.view.ImeInsetsSourceConsumerProto.HAS_PENDING_REQUEST;
import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER;
import static android.view.ImeInsetsSourceConsumerProto.IS_HIDE_ANIMATION_RUNNING;
import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL;
import static android.view.ImeInsetsSourceConsumerProto.IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION;

import android.annotation.Nullable;
import android.os.IBinder;
@@ -43,20 +42,16 @@ import java.util.function.Supplier;
public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {

    /**
     * Tracks whether we have an outstanding request from the IME to show, but weren't able to
     * execute it because we didn't have control yet.
     * Tracks whether are requested to show during the hide animation or requested to hide during
     * the show animation. If this is true, we should not remove the surface.
     */
    private boolean mIsRequestedVisibleAwaitingControl;

    private boolean mIsHideAnimationRunning;
    private boolean mHasPendingRequest;

    /**
     * Tracks whether {@link WindowInsetsController#show(int)} or
     * {@link InputMethodManager#showSoftInput(View, int)} is called during IME hide animation.
     * If it was called, we should not call {@link InputMethodManager#notifyImeHidden(IBinder,
     * ImeTracker.Token)}, because the IME is being shown.
     * Tracks whether we have an outstanding request from the IME to show, but weren't able to
     * execute it because we didn't have control yet.
     */
    private boolean mIsShowRequestedDuringHideAnimation;
    private boolean mIsRequestedVisibleAwaitingControl;

    public ImeInsetsSourceConsumer(
            int id, InsetsState state, Supplier<Transaction> transactionSupplier,
@@ -72,27 +67,19 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
                    mController.getHost().getInputMethodManager(), null /* icProto */);
        }
        final boolean insetsChanged = super.onAnimationStateChanged(running);
        final boolean showRequested = (mController.getRequestedVisibleTypes() & getType()) != 0;
        if (showRequested) {
            onShowRequested();
        } else {
        if (!isShowRequested()) {
            mIsRequestedVisibleAwaitingControl = false;
            if (!running) {
                // Remove IME surface as IME has finished hide animation, if there is no pending
                // show request.
                if (!mIsShowRequestedDuringHideAnimation) {
            if (!running && !mHasPendingRequest) {
                notifyHidden(null /* statsToken */);
                removeSurface();
            }
        }
            // Here is reached
            // (1) before the hide animation starts.
            // (2) after the hide animation ends.
            // (3) if the IME is not controllable (animationFinished == true in this case).
            // We should reset mIsShowRequestedDuringHideAnimation in all cases.
            mIsHideAnimationRunning = running;
            mIsShowRequestedDuringHideAnimation = false;
        }
        // This method is called
        // (1) after the animation starts.
        // (2) after the animation ends (including the case of cancel).
        // (3) if the IME is not controllable (running == false in this case).
        // We should reset mHasPendingRequest in all cases.
        mHasPendingRequest = false;
        return insetsChanged;
    }

@@ -132,6 +119,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
                    "ImeInsetsSourceConsumer#requestShow",
                    mController.getHost().getInputMethodManager(), null /* icProto */);
        }
        onShowRequested();

        // TODO: ResultReceiver for IME.
        // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag.
@@ -153,6 +141,17 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
                ? ShowResult.IME_SHOW_DELAYED : ShowResult.IME_SHOW_FAILED;
    }

    void requestHide(boolean fromIme, @Nullable ImeTracker.Token statsToken) {
        if (!fromIme) {
            // The insets might be controlled by a remote target. Let the server know we are
            // requested to hide.
            notifyHidden(statsToken);
        }
        if (mAnimationState == ANIMATION_STATE_SHOW) {
            mHasPendingRequest = true;
        }
    }

    /**
     * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that
     * IME insets are hidden.
@@ -222,18 +221,17 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
        final long token = proto.start(fieldId);
        super.dumpDebug(proto, INSETS_SOURCE_CONSUMER);
        proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl);
        proto.write(IS_HIDE_ANIMATION_RUNNING, mIsHideAnimationRunning);
        proto.write(IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION, mIsShowRequestedDuringHideAnimation);
        proto.write(HAS_PENDING_REQUEST, mHasPendingRequest);
        proto.end(token);
    }

    /**
     * Called when {@link #onAnimationStateChanged(boolean)} or
     * Called when {@link #requestShow(boolean, ImeTracker.Token)} or
     * {@link InputMethodManager#showSoftInput(View, int)} is called.
     */
    public void onShowRequested() {
        if (mIsHideAnimationRunning) {
            mIsShowRequestedDuringHideAnimation = true;
        if (mAnimationState == ANIMATION_STATE_HIDE) {
            mHasPendingRequest = true;
        }
    }

+6 −6
Original line number Diff line number Diff line
@@ -1203,8 +1203,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            return;
        }
        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);

        cancelExistingControllers(types);
        if (DEBUG) Log.d(TAG, "controlAnimation types: " + types);
        mLastStartedAnimTypes |= types;

@@ -1236,9 +1234,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                });
            }

            // The requested visibilities should be delayed as well. Otherwise, the server will
            // create already visible leashes for us before we play the show animation.
            setRequestedVisibleTypes(mReportedRequestedVisibleTypes, types);
            // The requested visibilities should be delayed as well. Otherwise, we might override
            // the insets visibility before playing animation.
            setRequestedVisibleTypes(mReportedRequestedVisibleTypes, typesReady);

            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
            if (!fromIme) {
@@ -1250,7 +1248,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (typesReady == 0) {
            if (DEBUG) Log.d(TAG, "No types ready. onCancelled()");
            listener.onCancelled(null);
            reportRequestedVisibleTypes();
            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
            if (!fromIme) {
                Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
@@ -1258,6 +1255,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            return;
        }

        cancelExistingControllers(typesReady);

        final InsetsAnimationControlRunner runner = useInsetsAnimationThread
                ? new InsetsAnimationThreadControlRunner(controls,
@@ -1344,6 +1342,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        setRequestedVisibleTypes(0 /* visibleTypes */, consumer.getType());
                        break;
                }
            } else {
                consumer.requestHide(fromIme, statsToken);
            }
            if (!canRun) {
                if (WARN) Log.w(TAG, String.format(
+31 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.view;
import static android.view.InsetsController.ANIMATION_TYPE_NONE;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsSourceConsumerProto.ANIMATION_STATE;
import static android.view.InsetsSourceConsumerProto.HAS_WINDOW_FOCUS;
import static android.view.InsetsSourceConsumerProto.INTERNAL_INSETS_TYPE;
import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE;
@@ -73,6 +74,12 @@ public class InsetsSourceConsumer {
        int IME_SHOW_FAILED = 2;
    }

    protected static final int ANIMATION_STATE_NONE = 0;
    protected static final int ANIMATION_STATE_SHOW = 1;
    protected static final int ANIMATION_STATE_HIDE = 2;

    protected int mAnimationState = ANIMATION_STATE_NONE;

    protected final InsetsController mController;
    protected final InsetsState mState;
    private int mId;
@@ -230,14 +237,31 @@ public class InsetsSourceConsumer {
            mPendingVisibleFrame = null;
        }

        final boolean showRequested = isShowRequested();
        final boolean cancelledForNewAnimation = !running && showRequested
                ? mAnimationState == ANIMATION_STATE_HIDE
                : mAnimationState == ANIMATION_STATE_SHOW;

        mAnimationState = running
                ? (showRequested ? ANIMATION_STATE_SHOW : ANIMATION_STATE_HIDE)
                : ANIMATION_STATE_NONE;

        // We apply the visibility override after the animation is started. We don't do this before
        // that because we need to know the initial insets state while creating the animation.
        // We also need to apply the override after the animation is finished because the requested
        // visibility can be set when finishing the user animation.
        // If the animation is cancelled because we are going to play a new animation with an
        // opposite direction, don't apply it now but after the new animation is started.
        if (!cancelledForNewAnimation) {
            insetsChanged |= applyLocalVisibilityOverride();
        }
        return insetsChanged;
    }

    protected boolean isShowRequested() {
        return (mController.getRequestedVisibleTypes() & getType()) != 0;
    }

    /**
     * Called when current window gains focus
     */
@@ -300,6 +324,10 @@ public class InsetsSourceConsumer {
        return ShowResult.SHOW_IMMEDIATELY;
    }

    void requestHide(boolean fromController, @Nullable ImeTracker.Token statsToken) {
        // no-op for types that always return ShowResult#SHOW_IMMEDIATELY.
    }

    /**
     * Reports that this source's perceptibility has changed
     *
@@ -364,7 +392,7 @@ public class InsetsSourceConsumer {
        final long token = proto.start(fieldId);
        proto.write(INTERNAL_INSETS_TYPE, WindowInsets.Type.toString(mType));
        proto.write(HAS_WINDOW_FOCUS, mHasWindowFocus);
        proto.write(IS_REQUESTED_VISIBLE, (mController.getRequestedVisibleTypes() & mType) != 0);
        proto.write(IS_REQUESTED_VISIBLE, isShowRequested());
        if (mSourceControl != null) {
            mSourceControl.dumpDebug(proto, SOURCE_CONTROL);
        }
@@ -374,6 +402,7 @@ public class InsetsSourceConsumer {
        if (mPendingVisibleFrame != null) {
            mPendingVisibleFrame.dumpDebug(proto, PENDING_VISIBLE_FRAME);
        }
        proto.write(ANIMATION_STATE, mAnimationState);
        proto.end(token);
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ message ImeInsetsSourceConsumerProto {
    optional InsetsSourceConsumerProto insets_source_consumer = 1;
    reserved 2; // focused_editor = 2
    optional bool is_requested_visible_awaiting_control = 3;
    optional bool is_hide_animation_running = 4;
    optional bool is_show_requested_during_hide_animation = 5;
    optional bool is_hide_animation_running = 4 [deprecated=true];
    optional bool is_show_requested_during_hide_animation = 5 [deprecated=true];
    optional bool has_pending_request = 6;
}
 No newline at end of file
+1 −0
Original line number Diff line number Diff line
@@ -33,4 +33,5 @@ message InsetsSourceConsumerProto {
    optional InsetsSourceControlProto source_control = 4;
    optional .android.graphics.RectProto pending_frame = 5;
    optional .android.graphics.RectProto pending_visible_frame = 6;
    optional int32 animation_state = 7;
}
 No newline at end of file