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

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

Merge "Changes in ImeTracker to be compatible with the InsetsController refactoring" into main

parents 383ebb65 ec8e715b
Loading
Loading
Loading
Loading
+36 −2
Original line number Diff line number Diff line
@@ -974,6 +974,11 @@ public class InputMethodService extends AbstractInputMethodService {
                                : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null);
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            if (android.view.inputmethod.Flags.refactorInsetsController()) {
                // The hide request first finishes the animation and then proceeds to the server
                // side, finally reaching here, marking this the end state.
                ImeTracker.forLogging().onHidden(statsToken);
            }
        }

        /**
@@ -3104,6 +3109,13 @@ public class InputMethodService extends AbstractInputMethodService {

        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_SHOW_WINDOW);

        if (android.view.inputmethod.Flags.refactorInsetsController()) {
            // The ImeInsetsSourceProvider need the statsToken when dispatching the control
            // (whenever the IME has drawn and its window is visible). Therefore, sending the
            // statsToken here first.
            notifyPreImeWindowVisibilityChanged(true /* visible */, statsToken);
        }

        ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", mDumper,
                null /* icProto */);
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow");
@@ -3127,7 +3139,9 @@ public class InputMethodService extends AbstractInputMethodService {
        if (DEBUG) Log.v(TAG, "showWindow: draw decorView!");
        mWindow.show();
        mDecorViewWasVisible = true;
        if (!android.view.inputmethod.Flags.refactorInsetsController()) {
            applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */, statsToken);
        }
        cancelImeSurfaceRemoval();
        mInShowWindow = false;
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3238,6 +3252,20 @@ public class InputMethodService extends AbstractInputMethodService {
                ? mCurShowInputToken : mCurHideInputToken, setVisible, statsToken);
    }

    /**
     * Notifies the ImeInsetsSourceProvider before the IME visibility changes.
     *
     * @param visible {@code true} if it became visible, {@code false} otherwise.
     * @param statsToken the token tracking the current IME request.
     */
    private void notifyPreImeWindowVisibilityChanged(boolean visible,
            @NonNull ImeTracker.Token statsToken) {
        final var viewRootImpl = getWindow().getWindow().getDecorView().getViewRootImpl();
        if (viewRootImpl != null) {
            viewRootImpl.notifyImeVisibilityChanged(visible, statsToken);
        }
    }

    private void finishViews(boolean finishingInput) {
        if (mInputViewStarted) {
            if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
@@ -3279,7 +3307,13 @@ public class InputMethodService extends AbstractInputMethodService {
        ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", mDumper,
                null /* icProto */);
        setImeWindowStatus(0, mBackDisposition);
        if (android.view.inputmethod.Flags.refactorInsetsController()) {
            // The ImeInsetsSourceProvider need the statsToken when dispatching the control. We
            // send the token here, so that another request in the provider can be cancelled.
            notifyPreImeWindowVisibilityChanged(false /* visible */, statsToken);
        } else {
            applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */, statsToken);
        }
        mWindowVisible = false;
        finishViews(false /* finishingInput */);
        if (mDecorViewVisible) {
+13 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.view.IWindow;
import android.view.IWindowId;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.inputmethod.ImeTracker;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.Surface;
@@ -276,7 +277,8 @@ interface IWindowSession {
    /**
     * Updates the requested visible types of insets.
     */
    oneway void updateRequestedVisibleTypes(IWindow window, int requestedVisibleTypes);
    oneway void updateRequestedVisibleTypes(IWindow window, int requestedVisibleTypes,
            in @nullable ImeTracker.Token imeStatsToken);

    /**
     * Called when the system gesture exclusion has changed.
@@ -369,4 +371,14 @@ interface IWindowSession {
     * @return {@code true} if the focus changes. Otherwise, {@code false}.
     */
    boolean moveFocusToAdjacentWindow(IWindow fromWindow, int direction);

    /**
     * Notifies the statsToken and IME visibility to the ImeInsetsSourceProvider.
     *
     * @param window The window that is used to get the ImeInsetsSourceProvider.
     * @param visible {@code true} to make it visible, {@code false} to hide it.
     * @param statsToken the token tracking the current IME request.
     */
    oneway void notifyImeWindowVisibilityChangedFromClient(IWindow window, boolean visible,
            in ImeTracker.Token statsToken);
}
+56 −19
Original line number Diff line number Diff line
@@ -121,8 +121,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
         * The visibilities should be reported back to WM.
         *
         * @param types Bitwise flags of types requested visible.
         * @param statsToken the token tracking the current IME request or {@code null} otherwise.
         */
        void updateRequestedVisibleTypes(@InsetsType int types);
        void updateRequestedVisibleTypes(@InsetsType int types,
                @Nullable ImeTracker.Token statsToken);

        /**
         * @return Whether the host has any callbacks it wants to synchronize the animations with.
@@ -974,6 +976,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        int consumedControlCount = 0;
        final @InsetsType int[] showTypes = new int[1];
        final @InsetsType int[] hideTypes = new int[1];
        ImeTracker.Token statsToken = null;

        // Ensure to update all existing source consumers
        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
@@ -988,6 +991,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            if (control != null) {
                controllableTypes |= control.getType();
                consumedControlCount++;

                if (Flags.refactorInsetsController()) {
                    if (control.getId() == ID_IME) {
                        statsToken = control.getImeStatsToken();
                    }
                }
            }

            // control may be null, but we still need to update the control to null if it got
@@ -1021,34 +1030,31 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (Flags.refactorInsetsController()) {
            if (mPendingImeControlRequest != null && getImeSourceConsumer().getControl() != null
                    && getImeSourceConsumer().getControl().getLeash() != null) {
                // TODO we need to pass the statsToken
                handlePendingControlRequest(null);
                handlePendingControlRequest(statsToken);
            } else {
                if (showTypes[0] != 0) {
                    applyAnimation(showTypes[0], true /* show */, false /* fromIme */,
                            null /* statsToken */);
                    applyAnimation(showTypes[0], true /* show */, false /* fromIme */, statsToken);
                }
                if (hideTypes[0] != 0) {
                    applyAnimation(hideTypes[0], false /* show */, false /* fromIme */,
                            null /* statsToken */);
                    applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, statsToken);
                }
            }
        } else {
            if (showTypes[0] != 0) {
                final var statsToken =
                final var newStatsToken =
                        (showTypes[0] & ime()) == 0 ? null : ImeTracker.forLogging().onStart(
                                ImeTracker.TYPE_SHOW, ImeTracker.ORIGIN_CLIENT,
                                SoftInputShowHideReason.CONTROLS_CHANGED,
                                mHost.isHandlingPointerEvent() /* fromUser */);
                applyAnimation(showTypes[0], true /* show */, false /* fromIme */, statsToken);
                applyAnimation(showTypes[0], true /* show */, false /* fromIme */, newStatsToken);
            }
            if (hideTypes[0] != 0) {
                final var statsToken =
                final var newStatsToken =
                        (hideTypes[0] & ime()) == 0 ? null : ImeTracker.forLogging().onStart(
                                ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT,
                                SoftInputShowHideReason.CONTROLS_CHANGED,
                                mHost.isHandlingPointerEvent() /* fromUser */);
                applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, statsToken);
                applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, newStatsToken);
            }
        }

@@ -1065,7 +1071,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        }

        // InsetsSourceConsumer#setControl might change the requested visibility.
        reportRequestedVisibleTypes();
        // TODO(b/353463205) check this: if the requestedVisibleTypes for the IME were already
        //  sent, the request would fail. Therefore, don't send the statsToken here.
        reportRequestedVisibleTypes(null /* statsToken */);
    }

    @VisibleForTesting(visibility = PACKAGE)
@@ -1176,6 +1184,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        }
        if (DEBUG) Log.d(TAG, "show typesReady: " + typesReady);
        if ((Flags.refactorInsetsController() || fromIme) && (typesReady & Type.ime()) != 0) {
            // TODO(b/353463205) check if this is needed here
            ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication);
        }
        applyAnimation(typesReady, true /* show */, fromIme, statsToken);
@@ -1243,6 +1252,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    // an animation again (mRequestedVisibleTypes are reported at the end of the IME
                    // hide animation but set at the beginning)
                    if ((mRequestedVisibleTypes & ime()) == 0) {
                        ImeTracker.forLogging().onCancelled(statsToken,
                                ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN);
                        continue;
                    }
                }
@@ -1346,7 +1357,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        // We are finishing setting the requested visible types. Report them to the server
        // and/or the app.
        reportRequestedVisibleTypes();
        reportRequestedVisibleTypes(statsToken);
    }

    private void controlAnimationUncheckedInner(@InsetsType int types,
@@ -1396,8 +1407,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            // Ime will not be contained in typesReady nor in controls, if we don't have a leash
            Pair<Integer, Integer> typesReadyPair = collectSourceControlsV2(types, controls);
            typesReady = typesReadyPair.first;
            @InsetsType int typesWithoutLeash = typesReadyPair.second;
            if (animationType == ANIMATION_TYPE_USER) {
                @InsetsType int typesWithoutLeash = typesReadyPair.second;
                // When using an app-driven animation, the IME won't have a leash (because the
                // window isn't created yet). If we have a control, but no leash, defers the
                // request until the leash gets created.
@@ -1431,6 +1442,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                }
                // We need to wait until all types are ready
                if (typesReady != types) {
                    if (DEBUG) {
                        Log.d(TAG, TextUtils.formatSimple(
                                "not all types are ready yet, waiting. typesReady: %s, types: %s",
                                typesReady, types));
                    }
                    return;
                }
            }
@@ -1728,9 +1744,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        } else {
            ImeTracker.forLogging().onProgress(statsToken,
                    ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_HIDE);
            // The requestedVisibleTypes are only send at the end of the hide animation.
            // Therefore, the requested is not finished at this point.
            if (!Flags.refactorInsetsController()) {
                ImeTracker.forLogging().onHidden(statsToken);
            }
        reportRequestedVisibleTypes();
        }
        reportRequestedVisibleTypes(shown ? null : runner.getStatsToken());
    }

    @Override
@@ -1787,7 +1807,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                            if (mHost != null) {
                                // if the (hide) animation is cancelled, the
                                // requestedVisibleTypes should be reported at this point.
                                reportRequestedVisibleTypes();
                                reportRequestedVisibleTypes(control.getStatsToken());
                                mHost.getInputMethodManager().removeImeSurface(
                                        mHost.getWindowToken());
                            }
@@ -1923,8 +1943,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

    /**
     * Called when finishing setting requested visible types or finishing setting controls.
     *
     * @param statsToken the token tracking the current IME request or {@code null} otherwise.
     */
    private void reportRequestedVisibleTypes() {
    private void reportRequestedVisibleTypes(@Nullable ImeTracker.Token statsToken) {
        final @InsetsType int typesToReport;
        if (Flags.refactorInsetsController()) {
            // If the IME is currently animating out, it is still visible, therefore we only
@@ -1941,8 +1963,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            if (WindowInsets.Type.hasCompatSystemBars(diff)) {
                mCompatSysUiVisibilityStaled = true;
            }
            if (Flags.refactorInsetsController()) {
                ImeTracker.forLogging().onProgress(statsToken,
                        ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES);
            }
            mReportedRequestedVisibleTypes = mRequestedVisibleTypes;
            mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes);
            mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes, statsToken);
        } else if (Flags.refactorInsetsController()) {
            if ((typesToReport & ime()) != 0 && mImeSourceConsumer != null) {
                InsetsSourceControl control = mImeSourceConsumer.getControl();
                if (control != null && control.getLeash() == null) {
                    // If the IME was requested twice, and we didn't receive the controls
                    // yet, this request will not continue. It should be cancelled here, as
                    // it would time out otherwise.
                    ImeTracker.forLogging().onCancelled(statsToken,
                            ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES);
                }
            }
        }
        updateCompatSysUiVisibility();
    }
+20 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.proto.ProtoOutputStream;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.ImeTracker;

import java.io.PrintWriter;
import java.util.Arrays;
@@ -56,6 +57,9 @@ public class InsetsSourceControl implements Parcelable {
    private boolean mSkipAnimationOnce;
    private int mParcelableFlags;

    /** The token tracking the current IME request */
    private @Nullable ImeTracker.Token mImeStatsToken;

    public InsetsSourceControl(int id, @InsetsType int type, @Nullable SurfaceControl leash,
            boolean initiallyVisible, Point surfacePosition, Insets insetsHint) {
        mId = id;
@@ -78,6 +82,7 @@ public class InsetsSourceControl implements Parcelable {
        mSurfacePosition = new Point(other.mSurfacePosition);
        mInsetsHint = other.mInsetsHint;
        mSkipAnimationOnce = other.getAndClearSkipAnimationOnce();
        mImeStatsToken = other.getImeStatsToken();
    }

    public InsetsSourceControl(Parcel in) {
@@ -88,6 +93,7 @@ public class InsetsSourceControl implements Parcelable {
        mSurfacePosition = in.readTypedObject(Point.CREATOR);
        mInsetsHint = in.readTypedObject(Insets.CREATOR);
        mSkipAnimationOnce = in.readBoolean();
        mImeStatsToken = in.readTypedObject(ImeTracker.Token.CREATOR);
    }

    public int getId() {
@@ -153,6 +159,15 @@ public class InsetsSourceControl implements Parcelable {
        return result;
    }

    @Nullable
    public ImeTracker.Token getImeStatsToken() {
        return mImeStatsToken;
    }

    public void setImeStatsToken(@Nullable ImeTracker.Token imeStatsToken) {
        mImeStatsToken = imeStatsToken;
    }

    public void setParcelableFlags(int parcelableFlags) {
        mParcelableFlags = parcelableFlags;
    }
@@ -171,6 +186,7 @@ public class InsetsSourceControl implements Parcelable {
        dest.writeTypedObject(mSurfacePosition, mParcelableFlags);
        dest.writeTypedObject(mInsetsHint, mParcelableFlags);
        dest.writeBoolean(mSkipAnimationOnce);
        dest.writeTypedObject(mImeStatsToken, mParcelableFlags);
    }

    public void release(Consumer<SurfaceControl> surfaceReleaseConsumer) {
@@ -196,13 +212,14 @@ public class InsetsSourceControl implements Parcelable {
                && mInitiallyVisible == that.mInitiallyVisible
                && mSurfacePosition.equals(that.mSurfacePosition)
                && mInsetsHint.equals(that.mInsetsHint)
                && mSkipAnimationOnce == that.mSkipAnimationOnce;
                && mSkipAnimationOnce == that.mSkipAnimationOnce
                && Objects.equals(mImeStatsToken, that.mImeStatsToken);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mId, mType, mLeash, mInitiallyVisible, mSurfacePosition, mInsetsHint,
                mSkipAnimationOnce);
                mSkipAnimationOnce, mImeStatsToken);
    }

    @Override
@@ -225,6 +242,7 @@ public class InsetsSourceControl implements Parcelable {
        pw.print(" mSurfacePosition="); pw.print(mSurfacePosition);
        pw.print(" mInsetsHint="); pw.print(mInsetsHint);
        pw.print(" mSkipAnimationOnce="); pw.print(mSkipAnimationOnce);
        pw.print(" mImeStatsToken="); pw.print(mImeStatsToken);
        pw.println();
    }

+18 −0
Original line number Diff line number Diff line
@@ -10056,6 +10056,24 @@ public final class ViewRootImpl implements ViewParent,
        mHandler.sendMessage(msg);
    }
    /**
     * Dispatches the statsToken and IME visibility to the ImeInsetsSourceProvider.
     *
     * @param visible {@code true} if it became visible, {@code false} otherwise.
     * @param statsToken the token tracking the current IME request.
     *
     * @hide
     */
    public void notifyImeVisibilityChanged(boolean visible, @NonNull ImeTracker.Token statsToken) {
        ImeTracker.forLogging().onProgress(statsToken,
                ImeTracker.PHASE_CLIENT_NOTIFY_IME_VISIBILITY_CHANGED);
        try {
            mWindowSession.notifyImeWindowVisibilityChangedFromClient(mWindow, visible, statsToken);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }
    /**
     * Represents a pending input event that is waiting in a queue.
     *
Loading