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

Commit 5841e87c authored by Hiroki Sato's avatar Hiroki Sato Committed by Automerger Merge Worker
Browse files

Merge changes from topics "presubmit-am-166ca8e59ac8499bb6b4f4cad6aae045",...

Merge changes from topics "presubmit-am-166ca8e59ac8499bb6b4f4cad6aae045", "presubmit-am-1a825bf4d182432b91541a8629e0e351" into tm-dev am: 2c06ff3d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17376444



Change-Id: I20267bea6995e486509e9c7b88414cd9c5027c25
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents d5968a9a 2c06ff3d
Loading
Loading
Loading
Loading
+83 −21
Original line number Diff line number Diff line
@@ -415,7 +415,7 @@ public final class CursorAnchorInfo implements Parcelable {
                            "required when positional parameters are specified.");
                }
            }
            return new CursorAnchorInfo(this);
            return CursorAnchorInfo.create(this);
        }

        /**
@@ -440,31 +440,93 @@ public final class CursorAnchorInfo implements Parcelable {
        }
    }

    private CursorAnchorInfo(final Builder builder) {
        mSelectionStart = builder.mSelectionStart;
        mSelectionEnd = builder.mSelectionEnd;
        mComposingTextStart = builder.mComposingTextStart;
        mComposingText = builder.mComposingText;
        mInsertionMarkerFlags = builder.mInsertionMarkerFlags;
        mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal;
        mInsertionMarkerTop = builder.mInsertionMarkerTop;
        mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
        mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
        mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null
                ? builder.mCharacterBoundsArrayBuilder.build() : null;
        mEditorBoundsInfo = builder.mEditorBoundsInfo;
        mMatrixValues = new float[9];
    private static CursorAnchorInfo create(Builder builder) {
        final SparseRectFArray characterBoundsArray =
                builder.mCharacterBoundsArrayBuilder != null
                        ? builder.mCharacterBoundsArrayBuilder.build()
                        : null;
        final float[] matrixValues = new float[9];
        if (builder.mMatrixInitialized) {
            System.arraycopy(builder.mMatrixValues, 0, mMatrixValues, 0, 9);
            System.arraycopy(builder.mMatrixValues, 0, matrixValues, 0, 9);
        } else {
            Matrix.IDENTITY_MATRIX.getValues(mMatrixValues);
            Matrix.IDENTITY_MATRIX.getValues(matrixValues);
        }

        return new CursorAnchorInfo(builder.mSelectionStart, builder.mSelectionEnd,
                builder.mComposingTextStart, builder.mComposingText, builder.mInsertionMarkerFlags,
                builder.mInsertionMarkerHorizontal, builder.mInsertionMarkerTop,
                builder.mInsertionMarkerBaseline, builder.mInsertionMarkerBottom,
                characterBoundsArray, builder.mEditorBoundsInfo, matrixValues);
    }

    private CursorAnchorInfo(int selectionStart, int selectionEnd, int composingTextStart,
            @Nullable CharSequence composingText, int insertionMarkerFlags,
            float insertionMarkerHorizontal, float insertionMarkerTop,
            float insertionMarkerBaseline, float insertionMarkerBottom,
            @Nullable SparseRectFArray characterBoundsArray,
            @Nullable EditorBoundsInfo editorBoundsInfo,
            @NonNull float[] matrixValues) {
        mSelectionStart = selectionStart;
        mSelectionEnd = selectionEnd;
        mComposingTextStart = composingTextStart;
        mComposingText = composingText;
        mInsertionMarkerFlags = insertionMarkerFlags;
        mInsertionMarkerHorizontal = insertionMarkerHorizontal;
        mInsertionMarkerTop = insertionMarkerTop;
        mInsertionMarkerBaseline = insertionMarkerBaseline;
        mInsertionMarkerBottom = insertionMarkerBottom;
        mCharacterBoundsArray = characterBoundsArray;
        mEditorBoundsInfo = editorBoundsInfo;
        mMatrixValues = matrixValues;

        // To keep hash function simple, we only use some complex objects for hash.
        int hash = Objects.hashCode(mComposingText);
        hash *= 31;
        hash += Arrays.hashCode(mMatrixValues);
        mHashCode = hash;
        int hashCode = Objects.hashCode(mComposingText);
        hashCode *= 31;
        hashCode += Arrays.hashCode(mMatrixValues);
        mHashCode = hashCode;
    }

    /**
     * Creates a new instance of {@link CursorAnchorInfo} by applying {@code parentMatrix} to
     * the coordinate transformation matrix.
     *
     * @param original     {@link CursorAnchorInfo} to be cloned from.
     * @param parentMatrix {@link Matrix} to be applied to {@code original.getMatrix()}
     * @return A new instance of {@link CursorAnchorInfo} whose {@link CursorAnchorInfo#getMatrix()}
     *         returns {@code parentMatrix * original.getMatrix()}.
     * @hide
     */
    public static CursorAnchorInfo createForAdditionalParentMatrix(CursorAnchorInfo original,
            @NonNull Matrix parentMatrix) {
        return new CursorAnchorInfo(original.mSelectionStart, original.mSelectionEnd,
                original.mComposingTextStart, original.mComposingText,
                original.mInsertionMarkerFlags, original.mInsertionMarkerHorizontal,
                original.mInsertionMarkerTop, original.mInsertionMarkerBaseline,
                original.mInsertionMarkerBottom, original.mCharacterBoundsArray,
                original.mEditorBoundsInfo, computeMatrixValues(parentMatrix, original));
    }

    /**
     * Returns a float array that represents {@link Matrix} elements for
     * {@code parentMatrix * info.getMatrix()}.
     *
     * @param parentMatrix {@link Matrix} to be multiplied.
     * @param info         {@link CursorAnchorInfo} to provide {@link Matrix} to be multiplied.
     * @return {@code parentMatrix * info.getMatrix()}.
     */
    private static float[] computeMatrixValues(@NonNull Matrix parentMatrix,
            @NonNull CursorAnchorInfo info) {
        if (parentMatrix.isIdentity()) {
            return info.mMatrixValues;
        }

        final Matrix newMatrix = new Matrix();
        newMatrix.setValues(info.mMatrixValues);
        newMatrix.postConcat(parentMatrix);

        final float[] matrixValues = new float[9];
        newMatrix.getValues(matrixValues);
        return matrixValues;
    }

    /**
+107 −1
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.Binder;
@@ -452,6 +453,18 @@ public final class InputMethodManager {
     */
    private CursorAnchorInfo mCursorAnchorInfo = null;

    /**
     * A special {@link Matrix} that can be provided by the system when this instance is running
     * inside a virtual display.
     *
     * <p>If this is non-{@code null}, {@link #updateCursorAnchorInfo(View, CursorAnchorInfo)}
     * should be adjusted with this {@link Matrix}.</p>
     *
     * <p>{@code null} when not used.</p>
     */
    @GuardedBy("mH")
    private Matrix mVirtualDisplayToScreenMatrix = null;

    /**
     * As reported by {@link InputBindResult}. This value is determined by
     * {@link com.android.internal.R.styleable#InputMethod_suppressesSpellChecking}.
@@ -528,6 +541,7 @@ public final class InputMethodManager {
    static final int MSG_REPORT_FULLSCREEN_MODE = 10;
    static final int MSG_BIND_ACCESSIBILITY_SERVICE = 11;
    static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 12;
    static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30;

    private static boolean isAutofillUIShowing(View servedView) {
        AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class);
@@ -892,6 +906,7 @@ public final class InputMethodManager {
                                InputMethodSessionWrapper.createOrNull(res.method);
                        mCurId = res.id;
                        mBindSequence = res.sequence;
                        mVirtualDisplayToScreenMatrix = res.getVirtualDisplayToScreenMatrix();
                        mIsInputMethodSuppressingSpellChecker =
                                res.isInputMethodSuppressingSpellChecker;
                    }
@@ -1063,6 +1078,45 @@ public final class InputMethodManager {
                    }
                    return;
                }
                case MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX: {
                    final float[] matrixValues = (float[]) msg.obj;
                    final int bindSequence = msg.arg1;
                    synchronized (mH) {
                        if (mBindSequence != bindSequence) {
                            return;
                        }
                        if (matrixValues == null || mVirtualDisplayToScreenMatrix == null) {
                            // Either InputBoundResult#mVirtualDisplayToScreenMatrixValues is null
                            // OR this app is unbound from the parent VirtualDisplay. In this case,
                            // calling updateCursorAnchorInfo() isn't safe. Only clear the matrix.
                            mVirtualDisplayToScreenMatrix = null;
                            return;
                        }

                        final float[] currentValues = new float[9];
                        mVirtualDisplayToScreenMatrix.getValues(currentValues);
                        if (Arrays.equals(currentValues, matrixValues)) {
                            return;
                        }
                        mVirtualDisplayToScreenMatrix.setValues(matrixValues);

                        if (mCursorAnchorInfo == null || mCurrentInputMethodSession == null
                                || mServedInputConnection == null) {
                            return;
                        }
                        final boolean isMonitoring = (mRequestUpdateCursorAnchorInfoMonitorMode
                                & InputConnection.CURSOR_UPDATE_MONITOR) != 0;
                        if (!isMonitoring) {
                            return;
                        }
                        // Since the host VirtualDisplay is moved, we need to issue
                        // IMS#updateCursorAnchorInfo() again.
                        mCurrentInputMethodSession.updateCursorAnchorInfo(
                                CursorAnchorInfo.createForAdditionalParentMatrix(
                                        mCursorAnchorInfo, mVirtualDisplayToScreenMatrix));
                    }
                    return;
                }
            }
        }
    }
@@ -1127,6 +1181,12 @@ public final class InputMethodManager {
                    .sendToTarget();
        }

        @Override
        public void updateVirtualDisplayToScreenMatrix(int bindSequence, float[] matrixValues) {
            mH.obtainMessage(MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX, bindSequence, 0,
                    matrixValues).sendToTarget();
        }

        @Override
        public void setImeTraceEnabled(boolean enabled) {
            ImeTracing.getInstance().setEnabled(enabled);
@@ -1596,7 +1656,9 @@ public final class InputMethodManager {
     * Disconnect any existing input connection, clearing the served view.
     */
    @UnsupportedAppUsage
    @GuardedBy("mH")
    void finishInputLocked() {
        mVirtualDisplayToScreenMatrix = null;
        mIsInputMethodSuppressingSpellChecker = false;
        setNextServedViewLocked(null);
        if (getServedViewLocked() != null) {
@@ -2275,6 +2337,7 @@ public final class InputMethodManager {
                        + InputMethodDebug.startInputFlagsToString(startInputFlags));
                return false;
            }
            mVirtualDisplayToScreenMatrix = res.getVirtualDisplayToScreenMatrix();
            mIsInputMethodSuppressingSpellChecker = res.isInputMethodSuppressingSpellChecker;
            if (res.id != null) {
                setInputChannelLocked(res.channel);
@@ -2695,7 +2758,13 @@ public final class InputMethodManager {
                return;
            }
            if (DEBUG) Log.v(TAG, "updateCursorAnchorInfo: " + cursorAnchorInfo);
            if (mVirtualDisplayToScreenMatrix != null) {
                mCurrentInputMethodSession.updateCursorAnchorInfo(
                        CursorAnchorInfo.createForAdditionalParentMatrix(
                                cursorAnchorInfo, mVirtualDisplayToScreenMatrix));
            } else {
                mCurrentInputMethodSession.updateCursorAnchorInfo(cursorAnchorInfo);
            }
            mCursorAnchorInfo = cursorAnchorInfo;
            // Clear immediate bit (if any).
            mRequestUpdateCursorAnchorInfoMonitorMode &= ~CURSOR_UPDATE_IMMEDIATE;
@@ -3268,6 +3337,43 @@ public final class InputMethodManager {
        }
    }

    /**
     * An internal API for {@link android.hardware.display.VirtualDisplay} to report where its
     * embedded virtual display is placed.
     *
     * @param childDisplayId Display ID of the embedded virtual display.
     * @param matrix         {@link Matrix} to convert virtual display screen coordinates to
     *                       the host screen coordinates. {@code null} to clear the relationship.
     * @hide
     */
    public void reportVirtualDisplayGeometry(int childDisplayId, @Nullable Matrix matrix) {
        try {
            final float[] matrixValues;
            if (matrix == null) {
                matrixValues = null;
            } else {
                matrixValues = new float[9];
                matrix.getValues(matrixValues);
            }
            mService.reportVirtualDisplayGeometryAsync(mClient, childDisplayId, matrixValues);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * An internal API that returns if the current display has a transformation matrix to apply.
     *
     * @return {@code true} if {@link Matrix} to convert virtual display screen coordinates to
     * the host screen coordinates is set.
     * @hide
     */
    public boolean hasVirtualDisplayToScreenMatrix() {
        synchronized (mH) {
            return mVirtualDisplayToScreenMatrix != null;
        }
    }

    /**
     * Force switch to the last used input method and subtype. If the last input method didn't have
     * any subtypes, the framework will simply switch to the last input method with no subtype
+30 −1
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@ package com.android.internal.inputmethod;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Matrix;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -202,11 +204,28 @@ public final class InputBindResult implements Parcelable {
     */
    public final int sequence;

    @Nullable
    private final float[] mVirtualDisplayToScreenMatrixValues;

    /**
     * {@code true} if the IME explicitly specifies {@code suppressesSpellChecker="true"}.
     */
    public final boolean isInputMethodSuppressingSpellChecker;

    /**
     * @return {@link Matrix} that corresponds to {@link #mVirtualDisplayToScreenMatrixValues}.
     *         {@code null} if {@link #mVirtualDisplayToScreenMatrixValues} is {@code null}.
     */
    @Nullable
    public Matrix getVirtualDisplayToScreenMatrix() {
        if (mVirtualDisplayToScreenMatrixValues == null) {
            return null;
        }
        final Matrix matrix = new Matrix();
        matrix.setValues(mVirtualDisplayToScreenMatrixValues);
        return matrix;
    }

    /**
     * Creates a new instance of {@link InputBindResult}.
     *
@@ -225,6 +244,7 @@ public final class InputBindResult implements Parcelable {
    public InputBindResult(@ResultCode int result,
            IInputMethodSession method, SparseArray<IInputMethodSession> accessibilitySessions,
            InputChannel channel, String id, int sequence,
            @Nullable Matrix virtualDisplayToScreenMatrix,
            boolean isInputMethodSuppressingSpellChecker) {
        this.result = result;
        this.method = method;
@@ -232,6 +252,12 @@ public final class InputBindResult implements Parcelable {
        this.channel = channel;
        this.id = id;
        this.sequence = sequence;
        if (virtualDisplayToScreenMatrix == null) {
            mVirtualDisplayToScreenMatrixValues = null;
        } else {
            mVirtualDisplayToScreenMatrixValues = new float[9];
            virtualDisplayToScreenMatrix.getValues(mVirtualDisplayToScreenMatrixValues);
        }
        this.isInputMethodSuppressingSpellChecker = isInputMethodSuppressingSpellChecker;
    }

@@ -258,6 +284,7 @@ public final class InputBindResult implements Parcelable {
        }
        id = source.readString();
        sequence = source.readInt();
        mVirtualDisplayToScreenMatrixValues = source.createFloatArray();
        isInputMethodSuppressingSpellChecker = source.readBoolean();
    }

@@ -268,6 +295,7 @@ public final class InputBindResult implements Parcelable {
    public String toString() {
        return "InputBindResult{result=" + getResultString() + " method=" + method + " id=" + id
                + " sequence=" + sequence
                + " virtualDisplayToScreenMatrix=" + getVirtualDisplayToScreenMatrix()
                + " isInputMethodSuppressingSpellChecker=" + isInputMethodSuppressingSpellChecker
                + "}";
    }
@@ -299,6 +327,7 @@ public final class InputBindResult implements Parcelable {
        }
        dest.writeString(id);
        dest.writeInt(sequence);
        dest.writeFloatArray(mVirtualDisplayToScreenMatrixValues);
        dest.writeBoolean(isInputMethodSuppressingSpellChecker);
    }

@@ -366,7 +395,7 @@ public final class InputBindResult implements Parcelable {
    }

    private static InputBindResult error(@ResultCode int result) {
        return new InputBindResult(result, null, null, null, null, -1, false);
        return new InputBindResult(result, null, null, null, null, -1, null, false);
    }

    /**
+2 −1
Original line number Diff line number Diff line
@@ -987,7 +987,8 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
            Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
            return false;
        }
        if (mParentInputMethodManager.getDisplayId() != imeDisplayId) {
        if (mParentInputMethodManager.getDisplayId() != imeDisplayId
                && !mParentInputMethodManager.hasVirtualDisplayToScreenMatrix()) {
            // requestCursorUpdates() is not currently supported across displays.
            return false;
        }
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ oneway interface IInputMethodClient {
    void setActive(boolean active, boolean fullscreen, boolean reportToImeController);
    void scheduleStartInputIfNecessary(boolean fullscreen);
    void reportFullscreenMode(boolean fullscreen);
    void updateVirtualDisplayToScreenMatrix(int bindSequence, in float[] matrixValues);
    void setImeTraceEnabled(boolean enabled);
    void throwExceptionFromSystem(String message);
}
Loading