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

Commit 72de8ead authored by Taran Singh's avatar Taran Singh
Browse files

Remove preRender input

Cleanup unused pre-render input. We've no plans to enable it.
It adds unnecessary complexity.

Bug: 159201509
Bug: 167948123
Bug: 118599175

Test: atest CtsInputMethodTestCases

Change-Id: I32fe3759b9aeb56c868f9abf42bab124b9b83374
parent 6a6ce5e6
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -213,8 +213,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
                        ic,
                        info,
                        moreArgs.argi1 == 1 /* restarting */,
                        startInputToken,
                        moreArgs.argi2 == 1 /* shouldPreRenderIme */);
                        startInputToken);
                args.recycle();
                moreArgs.recycle();
                return;
@@ -340,14 +339,13 @@ class IInputMethodWrapper extends IInputMethod.Stub
    @Override
    public void startInput(IBinder startInputToken, IInputContext inputContext,
            @InputConnectionInspector.MissingMethodFlags final int missingMethods,
            EditorInfo attribute, boolean restarting, boolean shouldPreRenderIme) {
            EditorInfo attribute, boolean restarting) {
        if (mCancellationGroup == null) {
            Log.e(TAG, "startInput must be called after bindInput.");
            mCancellationGroup = new CancellationGroup();
        }
        SomeArgs args = SomeArgs.obtain();
        args.argi1 = restarting ? 1 : 0;
        args.argi2 = shouldPreRenderIme ? 1 : 0;
        args.argi3 = missingMethods;
        mCaller.executeOrSendMessage(mCaller.obtainMessageOOOOO(DO_START_INPUT, startInputToken,
                inputContext, attribute, mCancellationGroup, args));
+14 −103
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package android.inputmethodservice;
import static android.graphics.Color.TRANSPARENT;
import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED;
import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY;
import static android.inputmethodservice.InputMethodServiceProto.CAN_PRE_RENDER;
import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION;
import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_VISIBLE;
import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_WAS_VISIBLE;
@@ -33,7 +32,6 @@ import static android.inputmethodservice.InputMethodServiceProto.INPUT_VIEW_STAR
import static android.inputmethodservice.InputMethodServiceProto.IN_SHOW_WINDOW;
import static android.inputmethodservice.InputMethodServiceProto.IS_FULLSCREEN;
import static android.inputmethodservice.InputMethodServiceProto.IS_INPUT_VIEW_SHOWN;
import static android.inputmethodservice.InputMethodServiceProto.IS_PRE_RENDERED;
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.CONTENT_TOP_INSETS;
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_INSETS;
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_REGION;
@@ -420,10 +418,6 @@ public class InputMethodService extends AbstractInputMethodService {
    boolean mDecorViewVisible;
    boolean mDecorViewWasVisible;
    boolean mInShowWindow;
    // True if pre-rendering of IME views/window is supported.
    boolean mCanPreRender;
    // If IME is pre-rendered.
    boolean mIsPreRendered;
    // IME window visibility.
    // Use (mDecorViewVisible && mWindowVisible) to check if IME is visible to the user.
    boolean mWindowVisible;
@@ -671,10 +665,8 @@ public class InputMethodService extends AbstractInputMethodService {
        @Override
        public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
                @NonNull EditorInfo editorInfo, boolean restarting,
                @NonNull IBinder startInputToken, boolean shouldPreRenderIme) {
                @NonNull IBinder startInputToken) {
            mPrivOps.reportStartInput(startInputToken);
            mCanPreRender = shouldPreRenderIme;
            if (DEBUG) Log.v(TAG, "Will Pre-render IME: " + mCanPreRender);

            if (restarting) {
                restartInput(inputConnection, editorInfo);
@@ -711,22 +703,12 @@ public class InputMethodService extends AbstractInputMethodService {
                        + " Use requestHideSelf(int) itself");
                return;
            }
            final boolean wasVisible = mIsPreRendered
                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
            final boolean wasVisible = isInputViewShown();
            applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */);
            if (mIsPreRendered) {
                if (DEBUG) {
                    Log.v(TAG, "Making IME window invisible");
                }
                setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition);
                onPreRenderedWindowVisibilityChanged(false /* setVisible */);
            } else {
            mShowInputFlags = 0;
            mShowInputRequested = false;
            doHideWindow();
            }
            final boolean isVisible = mIsPreRendered
                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
            final boolean isVisible = isInputViewShown();
            final boolean visibilityChanged = isVisible != wasVisible;
            if (resultReceiver != null) {
                resultReceiver.send(visibilityChanged
@@ -765,23 +747,15 @@ public class InputMethodService extends AbstractInputMethodService {
                        + " Use requestShowSelf(int) itself");
                return;
            }
            final boolean wasVisible = mIsPreRendered
                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
            final boolean wasVisible = isInputViewShown();
            if (dispatchOnShowInputRequested(flags, false)) {
                if (mIsPreRendered) {
                    if (DEBUG) {
                        Log.v(TAG, "Making IME window visible");
                    }
                    onPreRenderedWindowVisibilityChanged(true /* setVisible */);
                } else {

                showWindow(true);
                }
                applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */);
            }
            // If user uses hard keyboard, IME button should always be shown.
            setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
            final boolean isVisible = mIsPreRendered
                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
            final boolean isVisible = isInputViewShown();
            final boolean visibilityChanged = isVisible != wasVisible;
            if (resultReceiver != null) {
                resultReceiver.send(visibilityChanged
@@ -1788,7 +1762,7 @@ public class InputMethodService extends AbstractInputMethodService {
     * applied by {@link #updateInputViewShown()}.
     */
    public boolean isInputViewShown() {
        return mCanPreRender ? mWindowVisible : mIsInputViewShown && mDecorViewVisible;
        return mDecorViewVisible;
    }

    /**
@@ -2141,10 +2115,9 @@ public class InputMethodService extends AbstractInputMethodService {

        mDecorViewWasVisible = mDecorViewVisible;
        mInShowWindow = true;
        boolean isPreRenderedAndInvisible = mIsPreRendered && !mWindowVisible;
        final int previousImeWindowStatus =
                (mDecorViewVisible ? IME_ACTIVE : 0) | (isInputViewShown()
                        ? (isPreRenderedAndInvisible ? IME_INVISIBLE : IME_VISIBLE) : 0);
                        ? (!mWindowVisible ? IME_INVISIBLE : IME_VISIBLE) : 0);
        startViews(prepareWindow(showInput));
        final int nextImeWindowStatus = mapToImeWindowStatus();
        if (previousImeWindowStatus != nextImeWindowStatus) {
@@ -2153,14 +2126,7 @@ public class InputMethodService extends AbstractInputMethodService {

        // compute visibility
        onWindowShown();
        mIsPreRendered = mCanPreRender;
        if (mIsPreRendered) {
            onPreRenderedWindowVisibilityChanged(true /* setVisible */);
        } else {
            // Pre-rendering not supported.
            if (DEBUG) Log.d(TAG, "No pre-rendering supported");
        mWindowVisible = true;
        }

        // request draw for the IME surface.
        // When IME is not pre-rendered, this will actually show the IME.
@@ -2168,22 +2134,10 @@ public class InputMethodService extends AbstractInputMethodService {
            if (DEBUG) Log.v(TAG, "showWindow: draw decorView!");
            mWindow.show();
        }
        maybeNotifyPreRendered();
        mDecorViewWasVisible = true;
        mInShowWindow = false;
    }

    /**
     * Notify {@link android.view.ImeInsetsSourceConsumer} if IME has been pre-rendered
     * for current EditorInfo, when pre-rendering is enabled.
     */
    private void maybeNotifyPreRendered() {
        if (!mCanPreRender || !mIsPreRendered) {
            return;
        }
        mPrivOps.reportPreRendered(getCurrentInputEditorInfo());
    }


    private boolean prepareWindow(boolean showInput) {
        boolean doShowInput = false;
@@ -2227,16 +2181,6 @@ public class InputMethodService extends AbstractInputMethodService {
        if (doShowInput) startExtractingText(false);
    }

    private void onPreRenderedWindowVisibilityChanged(boolean setVisible) {
        mWindowVisible = setVisible;
        mShowInputFlags = setVisible ? mShowInputFlags : 0;
        mShowInputRequested = setVisible;
        mDecorViewVisible = setVisible;
        if (setVisible) {
            onWindowShown();
        }
    }

    /**
     * Applies the IME visibility in {@link android.view.ImeInsetsSourceConsumer}.
     *
@@ -2267,7 +2211,6 @@ public class InputMethodService extends AbstractInputMethodService {

    public void hideWindow() {
        if (DEBUG) Log.v(TAG, "CALL: hideWindow");
        mIsPreRendered = false;
        mWindowVisible = false;
        finishViews(false /* finishingInput */);
        if (mDecorViewVisible) {
@@ -2374,32 +2317,6 @@ public class InputMethodService extends AbstractInputMethodService {
                mCandidatesViewStarted = true;
                onStartCandidatesView(mInputEditorInfo, restarting);
            }
        } else if (mCanPreRender && mInputEditorInfo != null && mStartedInputConnection != null) {
            // Pre-render IME views and window when real EditorInfo is available.
            // pre-render IME window and keep it invisible.
            if (DEBUG) Log.v(TAG, "Pre-Render IME for " + mInputEditorInfo.fieldName);
            if (mInShowWindow) {
                Log.w(TAG, "Re-entrance in to showWindow");
                return;
            }

            mDecorViewWasVisible = mDecorViewVisible;
            mInShowWindow = true;
            startViews(prepareWindow(true /* showInput */));

            // compute visibility
            mIsPreRendered = true;
            onPreRenderedWindowVisibilityChanged(false /* setVisible */);

            // request draw for the IME surface.
            // When IME is not pre-rendered, this will actually show the IME.
            if (DEBUG) Log.v(TAG, "showWindow: draw decorView!");
            mWindow.show();
            maybeNotifyPreRendered();
            mDecorViewWasVisible = true;
            mInShowWindow = false;
        } else {
            mIsPreRendered = false;
        }
    }
    
@@ -3299,9 +3216,7 @@ public class InputMethodService extends AbstractInputMethodService {

    private int mapToImeWindowStatus() {
        return IME_ACTIVE
                | (isInputViewShown()
                        ? (mCanPreRender ? (mWindowVisible ? IME_VISIBLE : IME_INVISIBLE)
                        : IME_VISIBLE) : 0);
                | (isInputViewShown() ? IME_VISIBLE : 0);
    }

    private boolean isAutomotive() {
@@ -3339,8 +3254,6 @@ public class InputMethodService extends AbstractInputMethodService {

        p.println("  mShowInputRequested=" + mShowInputRequested
                + " mLastShowInputRequested=" + mLastShowInputRequested
                + " mCanPreRender=" + mCanPreRender
                + " mIsPreRendered=" + mIsPreRendered
                + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags));
        p.println("  mCandidatesVisibility=" + mCandidatesVisibility
                + " mFullscreenApplied=" + mFullscreenApplied
@@ -3391,8 +3304,6 @@ public class InputMethodService extends AbstractInputMethodService {
        }
        proto.write(SHOW_INPUT_REQUESTED, mShowInputRequested);
        proto.write(LAST_SHOW_INPUT_REQUESTED, mLastShowInputRequested);
        proto.write(CAN_PRE_RENDER, mCanPreRender);
        proto.write(IS_PRE_RENDERED, mIsPreRendered);
        proto.write(SHOW_INPUT_FLAGS, mShowInputFlags);
        proto.write(CANDIDATES_VISIBILITY, mCandidatesVisibility);
        proto.write(FULLSCREEN_APPLIED, mFullscreenApplied);
+0 −94
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.view;

import static android.view.ImeInsetsSourceConsumerProto.FOCUSED_EDITOR;
import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER;
import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL;
import static android.view.InsetsController.AnimationType;
@@ -25,16 +24,10 @@ import static android.view.InsetsState.ITYPE_IME;
import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.Parcel;
import android.text.TextUtils;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl.Transaction;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;

import com.android.internal.annotations.VisibleForTesting;

import java.util.Arrays;
import java.util.function.Supplier;

/**
@@ -42,13 +35,6 @@ import java.util.function.Supplier;
 * @hide
 */
public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    private EditorInfo mFocusedEditor;
    private EditorInfo mPreRenderedEditor;
    /**
     * Determines if IME would be shown next time IME is pre-rendered for currently focused
     * editor {@link #mFocusedEditor} if {@link #isServedEditorRendered} is {@code true}.
     */
    private boolean mShowOnNextImeRender;

    /**
     * Tracks whether we have an outstanding request from the IME to show, but weren't able to
@@ -62,23 +48,6 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
        super(ITYPE_IME, state, transactionSupplier, controller);
    }

    public void onPreRendered(EditorInfo info) {
        mPreRenderedEditor = info;
        if (mShowOnNextImeRender) {
            mShowOnNextImeRender = false;
            if (isServedEditorRendered()) {
                applyImeVisibility(true /* setVisible */);
            }
        }
    }

    public void onServedEditorChanged(EditorInfo info) {
        if (isFallbackOrEmptyEditor(info)) {
            mShowOnNextImeRender = false;
        }
        mFocusedEditor = info;
    }

    public void applyImeVisibility(boolean setVisible) {
        mController.applyImeVisibility(setVisible);
    }
@@ -170,73 +139,10 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
        }
    }

    private boolean isFallbackOrEmptyEditor(EditorInfo info) {
        // TODO(b/123044812): Handle fallback input gracefully in IME Insets API
        return info == null || (info.fieldId <= 0 && info.inputType <= 0);
    }

    private boolean isServedEditorRendered() {
        if (mFocusedEditor == null || mPreRenderedEditor == null
                || isFallbackOrEmptyEditor(mFocusedEditor)
                || isFallbackOrEmptyEditor(mPreRenderedEditor)) {
            // No view is focused or ready.
            return false;
        }
        return areEditorsSimilar(mFocusedEditor, mPreRenderedEditor);
    }

    @VisibleForTesting
    public static boolean areEditorsSimilar(EditorInfo info1, EditorInfo info2) {
        // We don't need to compare EditorInfo.fieldId (View#id) since that shouldn't change
        // IME views.
        boolean areOptionsSimilar =
                info1.imeOptions == info2.imeOptions
                && info1.inputType == info2.inputType
                && TextUtils.equals(info1.packageName, info2.packageName);
        areOptionsSimilar &= info1.privateImeOptions != null
                ? info1.privateImeOptions.equals(info2.privateImeOptions) : true;

        if (!areOptionsSimilar) {
            return false;
        }

        // compare bundle extras.
        if ((info1.extras == null && info2.extras == null) || info1.extras == info2.extras) {
            return true;
        }
        if ((info1.extras == null && info2.extras != null)
                || (info1.extras == null && info2.extras != null)) {
            return false;
        }
        if (info1.extras.hashCode() == info2.extras.hashCode()
                || info1.extras.equals(info1)) {
            return true;
        }
        if (info1.extras.size() != info2.extras.size()) {
            return false;
        }
        if (info1.extras.toString().equals(info2.extras.toString())) {
            return true;
        }

        // Compare bytes
        Parcel parcel1 = Parcel.obtain();
        info1.extras.writeToParcel(parcel1, 0);
        parcel1.setDataPosition(0);
        Parcel parcel2 = Parcel.obtain();
        info2.extras.writeToParcel(parcel2, 0);
        parcel2.setDataPosition(0);

        return Arrays.equals(parcel1.createByteArray(), parcel2.createByteArray());
    }

    @Override
    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
        super.dumpDebug(proto, INSETS_SOURCE_CONSUMER);
        if (mFocusedEditor != null) {
            mFocusedEditor.dumpDebug(proto, FOCUSED_EDITOR);
        }
        proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl);
        proto.end(token);
    }
+1 −1
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ public interface InputMethod {
    @MainThread
    default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
            @NonNull EditorInfo editorInfo, boolean restarting,
            @NonNull IBinder startInputToken, boolean shouldPreRenderIme) {
            @NonNull IBinder startInputToken) {
        if (restarting) {
            restartInput(inputConnection, editorInfo);
        } else {
+1 −34
Original line number Diff line number Diff line
@@ -489,7 +489,6 @@ public final class InputMethodManager {
    static final int MSG_TIMEOUT_INPUT_EVENT = 6;
    static final int MSG_FLUSH_INPUT_EVENT = 7;
    static final int MSG_REPORT_FULLSCREEN_MODE = 10;
    static final int MSG_REPORT_PRE_RENDERED = 15;
    static final int MSG_APPLY_IME_VISIBILITY = 20;
    static final int MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX = 30;

@@ -584,17 +583,6 @@ public final class InputMethodManager {
                mServedConnecting = true;
                servedView = getServedViewLocked();
            }
            if (servedView != null && servedView.getHandler() != null) {
                // Make sure View checks should be on the UI thread.
                servedView.getHandler().post(() -> {
                    if (!servedView.onCheckIsTextEditor()) {
                        // servedView has changed and it's not editable.
                        synchronized (mH) {
                            maybeCallServedViewChangedLocked(null);
                        }
                    }
                });
            }
            return startInputInner(startInputReason,
                    focusedView != null ? focusedView.getWindowToken() : null, startInputFlags,
                    softInputMode, windowFlags);
@@ -919,15 +907,6 @@ public final class InputMethodManager {
                    }
                    return;
                }
                case MSG_REPORT_PRE_RENDERED: {
                    synchronized (mH) {
                        if (mImeInsetsConsumer != null) {
                            mImeInsetsConsumer.onPreRendered((EditorInfo) msg.obj);
                        }
                    }
                    return;

                }
                case MSG_APPLY_IME_VISIBILITY: {
                    synchronized (mH) {
                        if (mImeInsetsConsumer != null) {
@@ -1099,12 +1078,6 @@ public final class InputMethodManager {
                    .sendToTarget();
        }

        @Override
        public void reportPreRendered(EditorInfo info) {
            mH.obtainMessage(MSG_REPORT_PRE_RENDERED, 0, 0, info)
                    .sendToTarget();
        }

        @Override
        public void applyImeVisibility(boolean setVisible) {
            mH.obtainMessage(MSG_APPLY_IME_VISIBILITY, setVisible ? 1 : 0, 0)
@@ -1981,7 +1954,7 @@ public final class InputMethodManager {

            // Hook 'em up and let 'er rip.
            mCurrentTextBoxAttribute = tba;
            maybeCallServedViewChangedLocked(tba);

            mServedConnecting = false;
            if (mServedInputConnectionWrapper != null) {
                mServedInputConnectionWrapper.deactivate();
@@ -3141,12 +3114,6 @@ public final class InputMethodManager {
        }
    }

    private void maybeCallServedViewChangedLocked(EditorInfo tba) {
        if (mImeInsetsConsumer != null) {
            mImeInsetsConsumer.onServedEditorChanged(tba);
        }
    }

    /**
     * <p>This is used for CTS test only. Do not use this method outside of CTS package.<p/>
     * @return the ID of this display which this {@link InputMethodManager} resides
Loading