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

Commit 15a7e289 authored by Cosmin Băieș's avatar Cosmin Băieș Committed by Android (Google) Code Review
Browse files

Merge "Handle IME user animation in ImeTracker" into main

parents 944c3298 43c85eb0
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -1262,10 +1262,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    mHost.getInputMethodManager(), null /* icProto */);
        }

        final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_USER,
                ImeTracker.ORIGIN_CLIENT, SoftInputShowHideReason.CONTROL_WINDOW_INSETS_ANIMATION,
                mHost.isHandlingPointerEvent() /* fromUser */);
        controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
                interpolator, animationType,
                getLayoutInsetsDuringAnimationMode(types, fromPredictiveBack),
                false /* useInsetsAnimationThread */, null /* statsToken */);
                false /* useInsetsAnimationThread */, statsToken);
    }

    private void controlAnimationUnchecked(@InsetsType int types,
@@ -1567,7 +1570,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            return;
        }
        final ImeTracker.Token statsToken = runner.getStatsToken();
        if (shown) {
        if (runner.getAnimationType() == ANIMATION_TYPE_USER) {
            ImeTracker.forLogging().onUserFinished(statsToken, shown);
        } else if (shown) {
            ImeTracker.forLogging().onProgress(statsToken,
                    ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_SHOW);
            ImeTracker.forLogging().onShown(statsToken);
@@ -1838,6 +1843,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.pendingAnim", 0);
            mHost.dispatchWindowInsetsAnimationStart(animation, bounds);
            mStartingAnimation = true;
            if (runner.getAnimationType() == ANIMATION_TYPE_USER) {
                ImeTracker.forLogging().onDispatched(runner.getStatsToken());
            }
            runner.setReadyDispatched(true);
            listener.onReady(runner, types);
            mStartingAnimation = false;
+13 −0
Original line number Diff line number Diff line
@@ -754,6 +754,19 @@ final class IInputMethodManagerGlobalInvoker {
        }
    }

    /** @see com.android.server.inputmethod.ImeTrackerService#onDispatched */
    static void onDispatched(@NonNull ImeTracker.Token statsToken) {
        final IImeTracker service = getImeTrackerService();
        if (service == null) {
            return;
        }
        try {
            service.onDispatched(statsToken);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** @see com.android.server.inputmethod.ImeTrackerService#hasPendingImeVisibilityRequests */
    @AnyThread
    @RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
+79 −15
Original line number Diff line number Diff line
@@ -71,24 +71,40 @@ public interface ImeTracker {
    /** The type of the IME request. */
    @IntDef(prefix = { "TYPE_" }, value = {
            TYPE_SHOW,
            TYPE_HIDE
            TYPE_HIDE,
            TYPE_USER,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Type {}

    /** IME show request type. */
    /**
     * IME show request type.
     *
     * @see android.view.InsetsController#ANIMATION_TYPE_SHOW
     */
    int TYPE_SHOW = ImeProtoEnums.TYPE_SHOW;

    /** IME hide request type. */
    /**
     * IME hide request type.
     *
     * @see android.view.InsetsController#ANIMATION_TYPE_HIDE
     */
    int TYPE_HIDE = ImeProtoEnums.TYPE_HIDE;

    /**
     * IME user-controlled animation request type.
     *
     * @see android.view.InsetsController#ANIMATION_TYPE_USER
     */
    int TYPE_USER = ImeProtoEnums.TYPE_USER;

    /** The status of the IME request. */
    @IntDef(prefix = { "STATUS_" }, value = {
            STATUS_RUN,
            STATUS_CANCEL,
            STATUS_FAIL,
            STATUS_SUCCESS,
            STATUS_TIMEOUT
            STATUS_TIMEOUT,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Status {}
@@ -117,7 +133,7 @@ public interface ImeTracker {
    @IntDef(prefix = { "ORIGIN_" }, value = {
            ORIGIN_CLIENT,
            ORIGIN_SERVER,
            ORIGIN_IME
            ORIGIN_IME,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Origin {}
@@ -400,19 +416,35 @@ public interface ImeTracker {
    void onCancelled(@Nullable Token token, @Phase int phase);

    /**
     * Called when the IME show request is successful.
     * Called when the show IME request is successful.
     *
     * @param token the token tracking the current IME request or {@code null} otherwise.
     */
    void onShown(@Nullable Token token);

    /**
     * Called when the IME hide request is successful.
     * Called when the hide IME request is successful.
     *
     * @param token the token tracking the current IME request or {@code null} otherwise.
     */
    void onHidden(@Nullable Token token);

    /**
     * Called when the user-controlled IME request was dispatched to the requesting app. The
     * user animation can take an undetermined amount of time, so it shouldn't be tracked.
     *
     * @param token the token tracking the current IME request or {@code null} otherwise.
     */
    void onDispatched(@Nullable Token token);

    /**
     * Called when the animation of the user-controlled IME request finished.
     *
     * @param token the token tracking the current IME request or {@code null} otherwise.
     * @param shown whether the end state of the animation was shown or hidden.
     */
    void onUserFinished(@Nullable Token token, boolean shown);

    /**
     * Returns whether the current IME request was created due to a user interaction. This can
     * only be {@code true} when running on the view's UI thread.
@@ -482,13 +514,6 @@ public interface ImeTracker {
        /** Whether the stack trace at the request call site should be logged. */
        private boolean mLogStackTrace;

        private void reloadSystemProperties() {
            mLogProgress = SystemProperties.getBoolean(
                    "persist.debug.imetracker", false);
            mLogStackTrace = SystemProperties.getBoolean(
                    "persist.debug.imerequest.logstacktrace", false);
        }

        @NonNull
        @Override
        public Token onStart(@NonNull String component, int uid, @Type int type, @Origin int origin,
@@ -497,7 +522,7 @@ public interface ImeTracker {
            final var token = IInputMethodManagerGlobalInvoker.onStart(tag, uid, type,
                    origin, reason, fromUser);

            Log.i(TAG, token.mTag + ": onRequest" + (type == TYPE_SHOW ? "Show" : "Hide")
            Log.i(TAG, token.mTag + ": " + getOnStartPrefix(type)
                    + " at " + Debug.originToString(origin)
                    + " reason " + InputMethodDebug.softInputDisplayReasonToString(reason)
                    + " fromUser " + fromUser,
@@ -552,6 +577,45 @@ public interface ImeTracker {

            Log.i(TAG, token.mTag + ": onHidden");
        }

        @Override
        public void onDispatched(@Nullable Token token) {
            if (token == null) return;
            IInputMethodManagerGlobalInvoker.onDispatched(token);

            Log.i(TAG, token.mTag + ": onDispatched");
        }

        @Override
        public void onUserFinished(@Nullable Token token, boolean shown) {
            if (token == null) return;
            // This is already sent to ImeTrackerService to mark it finished during onDispatched.

            Log.i(TAG, token.mTag + ": onUserFinished " + (shown ? "shown" : "hidden"));
        }

        /**
         * Gets the prefix string for {@link #onStart} based on the given request type.
         *
         * @param type request type for which to create the prefix string with.
         */
        @NonNull
        private static String getOnStartPrefix(@Type int type) {
            return switch (type) {
                case TYPE_SHOW -> "onRequestShow";
                case TYPE_HIDE -> "onRequestHide";
                case TYPE_USER -> "onRequestUser";
                default -> "onRequestUnknown";
            };
        }

        /** Reloads the system properties related to this class. */
        private void reloadSystemProperties() {
            mLogProgress = SystemProperties.getBoolean(
                    "persist.debug.imetracker", false);
            mLogStackTrace = SystemProperties.getBoolean(
                    "persist.debug.imerequest.logstacktrace", false);
        }
    };

    /** The singleton IME tracker instance for instrumenting jank metrics. */
+10 −2
Original line number Diff line number Diff line
@@ -64,19 +64,27 @@ interface IImeTracker {
    oneway void onCancelled(in ImeTracker.Token statsToken, int phase);

    /**
     * Called when the IME show request is successful.
     * Called when the show IME request is successful.
     *
     * @param statsToken the token tracking the current IME request.
     */
    oneway void onShown(in ImeTracker.Token statsToken);

    /**
     * Called when the IME hide request is successful.
     * Called when the hide IME request is successful.
     *
     * @param statsToken the token tracking the current IME request.
     */
    oneway void onHidden(in ImeTracker.Token statsToken);

    /**
     * Called when the user-controlled IME request was dispatched to the requesting app. The
     * user animation can take an undetermined amount of time, so it shouldn't be tracked.
     *
     * @param statsToken the token tracking the current IME request.
     */
    oneway void onDispatched(in ImeTracker.Token statsToken);

    /**
     * Checks whether there are any pending IME visibility requests.
     *
+2 −0
Original line number Diff line number Diff line
@@ -297,6 +297,8 @@ public final class InputMethodDebug {
                return "SHOW_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT";
            case SoftInputShowHideReason.SHOW_SOFT_INPUT_IMM_DEPRECATION:
                return "SHOW_SOFT_INPUT_IMM_DEPRECATION";
            case SoftInputShowHideReason.CONTROL_WINDOW_INSETS_ANIMATION:
                return "CONTROL_WINDOW_INSETS_ANIMATION";
            default:
                return "Unknown=" + reason;
        }
Loading