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

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

Merge "Refactor show/hide IME process" into main

parents 59724e7d d87895b9
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -55,4 +55,10 @@ oneway interface IDisplayWindowInsetsController {
     * @see IWindow#hideInsets
     */
    void hideInsets(int types, boolean fromIme, in @nullable ImeTracker.Token statsToken);

    /**
     * Reports the requested IME visibility of the IME input target to
     * the IDisplayWindowInsetsController
     */
    void setImeInputTargetRequestedVisibility(boolean visible);
}
+115 −91
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.IBinder;
import android.os.Trace;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl.Transaction;
import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;
import android.view.inputmethod.InputMethodManager;

@@ -61,17 +62,20 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {

    @Override
    public boolean onAnimationStateChanged(boolean running) {
        if (Flags.refactorInsetsController()) {
            return super.onAnimationStateChanged(running);
        } else {
            if (!running) {
                ImeTracing.getInstance().triggerClientDump(
                        "ImeInsetsSourceConsumer#onAnimationFinished",
                        mController.getHost().getInputMethodManager(), null /* icProto */);
            }
            boolean insetsChanged = super.onAnimationStateChanged(running);
        if (running && !isShowRequested() && mController.isPredictiveBackImeHideAnimInProgress()) {
            if (running && !isShowRequested()
                    && mController.isPredictiveBackImeHideAnimInProgress()) {
                // IME predictive back animation switched from pre-commit to post-commit.
                insetsChanged |= applyLocalVisibilityOverride();
            }

            if (!isShowRequested()) {
                mIsRequestedVisibleAwaitingLeash = false;
                if (!running && !mHasPendingRequest) {
@@ -91,22 +95,27 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
            mHasPendingRequest = false;
            return insetsChanged;
        }
    }

    @Override
    public void onWindowFocusGained(boolean hasViewFocus) {
        super.onWindowFocusGained(hasViewFocus);
        if (!Flags.refactorInsetsController()) {
            getImm().registerImeConsumer(this);
            if ((mController.getRequestedVisibleTypes() & getType()) != 0 && !hasLeash()) {
                mIsRequestedVisibleAwaitingLeash = true;
            }
        }
    }

    @Override
    public void onWindowFocusLost() {
        super.onWindowFocusLost();
        if (!Flags.refactorInsetsController()) {
            getImm().unregisterImeConsumer(this);
            mIsRequestedVisibleAwaitingLeash = false;
        }
    }

    @Override
    public boolean applyLocalVisibilityOverride() {
@@ -123,6 +132,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    @Override
    @ShowResult
    public int requestShow(boolean fromIme, @Nullable ImeTracker.Token statsToken) {
        if (!Flags.refactorInsetsController()) {
            if (fromIme) {
                ImeTracing.getInstance().triggerClientDump(
                        "ImeInsetsSourceConsumer#requestShow",
@@ -139,19 +149,24 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
                // If control or leash is null, schedule to show IME when both available.
                mIsRequestedVisibleAwaitingLeash = true;
            }
        // If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
        // this code here means that we now got control, so we can start the animation immediately.
        // If client window is trying to control IME and IME is already visible, it is immediate.
        if (fromIme
                || (mState.isSourceOrDefaultVisible(getId(), getType()) && hasLeash())) {
            // If we had a request before to show from IME (tracked with mImeRequestedShow),
            // reaching this code here means that we now got control, so we can start the
            // animation immediately. If client window is trying to control IME and IME is
            // already visible, it is immediate.
            if (fromIme || (mState.isSourceOrDefaultVisible(getId(), getType())
                    && hasLeash())) {
                return ShowResult.SHOW_IMMEDIATELY;
            }

            return getImm().requestImeShow(mController.getHost().getWindowToken(), statsToken)
                    ? ShowResult.IME_SHOW_DELAYED : ShowResult.IME_SHOW_FAILED;
        } else {
            return ShowResult.IME_SHOW_FAILED;
        }
    }

    void requestHide(boolean fromIme, @Nullable ImeTracker.Token statsToken) {
        if (!Flags.refactorInsetsController()) {
            if (!fromIme) {
                // Create a new token to track the hide request when we have control and leash,
                // as we use the passed in token for the insets animation already.
@@ -169,6 +184,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
                mHasPendingRequest = true;
            }
        }
    }

    /**
     * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that
@@ -177,6 +193,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
     * @param statsToken the token tracking the current IME request or {@code null} otherwise.
     */
    private void notifyHidden(@NonNull ImeTracker.Token statsToken) {
        if (!Flags.refactorInsetsController()) {
            ImeTracker.forLogging().onProgress(statsToken,
                    ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_NOTIFY_HIDDEN);

@@ -184,6 +201,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
            mIsRequestedVisibleAwaitingLeash = false;
            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
        }
    }

    @Override
    public void removeSurface() {
@@ -196,6 +214,9 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    @Override
    public boolean setControl(@Nullable InsetsSourceControl control, int[] showTypes,
            int[] hideTypes) {
        if (Flags.refactorInsetsController()) {
            return super.setControl(control, showTypes, hideTypes);
        } else {
            ImeTracing.getInstance().triggerClientDump("ImeInsetsSourceConsumer#setControl",
                    mController.getHost().getInputMethodManager(), null /* icProto */);
            if (!super.setControl(control, showTypes, hideTypes)) {
@@ -211,6 +232,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
            }
            return true;
        }
    }

    @Override
    protected boolean isRequestedVisibleAwaitingControl() {
@@ -228,11 +250,13 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    @Override
    public void onPerceptible(boolean perceptible) {
        super.onPerceptible(perceptible);
        if (!Flags.refactorInsetsController()) {
            final IBinder window = mController.getHost().getWindowToken();
            if (window != null) {
                getImm().reportPerceptible(window, perceptible);
            }
        }
    }

    @Override
    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
+282 −89

File changed.

Preview size limit exceeded, changes collapsed.

+59 −9
Original line number Diff line number Diff line
@@ -32,10 +32,13 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;

import com.android.internal.annotations.VisibleForTesting;
@@ -241,9 +244,15 @@ public class InsetsSourceConsumer {
        }

        final boolean showRequested = isShowRequested();
        final boolean cancelledForNewAnimation = !running && showRequested
        final boolean cancelledForNewAnimation;
        if (Flags.refactorInsetsController()) {
            cancelledForNewAnimation =
                    (mController.getCancelledForNewAnimationTypes() & mType) != 0;
        } else {
            cancelledForNewAnimation = (!running && showRequested)
                    ? mAnimationState == ANIMATION_STATE_HIDE
                    : mAnimationState == ANIMATION_STATE_SHOW;
        }

        mAnimationState = running
                ? (showRequested ? ANIMATION_STATE_SHOW : ANIMATION_STATE_HIDE)
@@ -292,13 +301,45 @@ public class InsetsSourceConsumer {
        }
        final boolean requestedVisible = (mController.getRequestedVisibleTypes() & mType) != 0;

        if (Flags.refactorInsetsController()) {
            // If we don't have control or the leash (in case of the IME), we enforce the
            // visibility to be hidden, as otherwise we would let the app know too early.
            if (mSourceControl == null) {
                if (DEBUG) {
                    Log.d(TAG, TextUtils.formatSimple(
                            "applyLocalVisibilityOverride: No control in %s for type %s, "
                                    + "requestedVisible=%s",
                            mController.getHost().getRootViewTitle(),
                            WindowInsets.Type.toString(mType), requestedVisible));
                }
                return false;
                // TODO(b/323136120) add a flag to the control, to define whether a leash is needed
            } else if (mId != InsetsSource.ID_IME_CAPTION_BAR
                    && mSourceControl.getLeash() == null) {
                if (DEBUG) {
                    Log.d(TAG, TextUtils.formatSimple(
                            "applyLocalVisibilityOverride: Set the source visibility to false, as"
                                    + " there is no leash yet for type %s in %s",
                            WindowInsets.Type.toString(mType),
                            mController.getHost().getRootViewTitle()));
                }
                boolean wasVisible = source.isVisible();
                source.setVisible(false);
                // only if it was visible before and is now hidden, we want to notify about the
                // changed state
                return wasVisible;
            }
        } else {
            // If we don't have control, we are not able to change the visibility.
            if (mSourceControl == null) {
            if (DEBUG) Log.d(TAG, "applyLocalVisibilityOverride: No control in "
                if (DEBUG) {
                    Log.d(TAG, "applyLocalVisibilityOverride: No control in "
                            + mController.getHost().getRootViewTitle()
                            + " requestedVisible=" + requestedVisible);
                }
                return false;
            }
        }
        if (source.isVisible() == requestedVisible) {
            return false;
        }
@@ -338,6 +379,15 @@ public class InsetsSourceConsumer {
     * @see InsetsAnimationControlCallbacks#reportPerceptible
     */
    public void onPerceptible(boolean perceptible) {
        if (Flags.refactorInsetsController()) {
            if (mType == WindowInsets.Type.ime()) {
                final IBinder window = mController.getHost().getWindowToken();
                if (window != null) {
                    mController.getHost().getInputMethodManager().reportPerceptible(window,
                            perceptible);
                }
            }
        }
    }

    /**
+0 −1
Original line number Diff line number Diff line
@@ -3288,7 +3288,6 @@ public final class ViewRootImpl implements ViewParent,
                        == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
    }
    @VisibleForTesting(visibility = PACKAGE)
    public InsetsController getInsetsController() {
        return mInsetsController;
    }
Loading