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

Commit 14d8e945 authored by Taran Singh's avatar Taran Singh Committed by Prabir Pradhan
Browse files

Scribe in IMF: CursorAnchorInfo#getEditorBoundsInfo 3/N

Add a new field EditorBoundsInfo in CursorAnchorInfo
and implement it.

Bug: 203086136
Test: atest CurosrAnchorInfoTest

Change-Id: I7f225fa1236534bbd18920f8ce8293df23ea2ce7
parent 2888d659
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -52972,6 +52972,7 @@ package android.view.inputmethod {
    method public int getCharacterBoundsFlags(int);
    method public int getCharacterBoundsFlags(int);
    method public CharSequence getComposingText();
    method public CharSequence getComposingText();
    method public int getComposingTextStart();
    method public int getComposingTextStart();
    method @Nullable public android.view.inputmethod.EditorBoundsInfo getEditorBoundsInfo();
    method public float getInsertionMarkerBaseline();
    method public float getInsertionMarkerBaseline();
    method public float getInsertionMarkerBottom();
    method public float getInsertionMarkerBottom();
    method public int getInsertionMarkerFlags();
    method public int getInsertionMarkerFlags();
@@ -52993,11 +52994,27 @@ package android.view.inputmethod {
    method public android.view.inputmethod.CursorAnchorInfo build();
    method public android.view.inputmethod.CursorAnchorInfo build();
    method public void reset();
    method public void reset();
    method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, CharSequence);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, CharSequence);
    method @NonNull public android.view.inputmethod.CursorAnchorInfo.Builder setEditorBoundsInfo(@Nullable android.view.inputmethod.EditorBoundsInfo);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, int);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, int);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
  }
  }
  public final class EditorBoundsInfo implements android.os.Parcelable {
    method public int describeContents();
    method @Nullable public android.graphics.RectF getEditorBounds();
    method @Nullable public android.graphics.RectF getHandwritingBounds();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.EditorBoundsInfo> CREATOR;
  }
  public static final class EditorBoundsInfo.Builder {
    ctor public EditorBoundsInfo.Builder();
    method @NonNull public android.view.inputmethod.EditorBoundsInfo build();
    method @NonNull public android.view.inputmethod.EditorBoundsInfo.Builder setEditorBounds(@Nullable android.graphics.RectF);
    method @NonNull public android.view.inputmethod.EditorBoundsInfo.Builder setHandwritingBounds(@Nullable android.graphics.RectF);
  }
  public class EditorInfo implements android.text.InputType android.os.Parcelable {
  public class EditorInfo implements android.text.InputType android.os.Parcelable {
    ctor public EditorInfo();
    ctor public EditorInfo();
    method public int describeContents();
    method public int describeContents();
+21 −2
Original line number Original line Diff line number Diff line
@@ -8663,12 +8663,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mAttachInfo == null) {
        if (mAttachInfo == null) {
            return;
            return;
        }
        }
        RectF position = mAttachInfo.mTmpTransformRect;
        getBoundsToScreenInternal(position, clipToParent);
        outRect.set(Math.round(position.left), Math.round(position.top),
                Math.round(position.right), Math.round(position.bottom));
    }
    /**
     * Gets the location of this view in screen coordinates.
     *
     * @param outRect The output location
     * @param clipToParent Whether to clip child bounds to the parent ones.
     * @hide
     */
    public void getBoundsOnScreen(RectF outRect, boolean clipToParent) {
        if (mAttachInfo == null) {
            return;
        }
        RectF position = mAttachInfo.mTmpTransformRect;
        RectF position = mAttachInfo.mTmpTransformRect;
        getBoundsToScreenInternal(position, clipToParent);
        outRect.set(position.left, position.top, position.right, position.bottom);
    }
    private void getBoundsToScreenInternal(RectF position, boolean clipToParent) {
        position.set(0, 0, mRight - mLeft, mBottom - mTop);
        position.set(0, 0, mRight - mLeft, mBottom - mTop);
        mapRectFromViewToScreenCoords(position, clipToParent);
        mapRectFromViewToScreenCoords(position, clipToParent);
        outRect.set(Math.round(position.left), Math.round(position.top),
                Math.round(position.right), Math.round(position.bottom));
    }
    }
    /**
    /**
+36 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,13 @@ public final class CursorAnchorInfo implements Parcelable {
     */
     */
    private final SparseRectFArray mCharacterBoundsArray;
    private final SparseRectFArray mCharacterBoundsArray;


    /**
     * Container of rectangular position of Editor in the local coordinates that will be transformed
     * with the transformation matrix when rendered on the screen.
     * @see {@link EditorBoundsInfo}.
     */
    private final EditorBoundsInfo mEditorBoundsInfo;

    /**
    /**
     * Transformation matrix that is applied to any positional information of this class to
     * Transformation matrix that is applied to any positional information of this class to
     * transform local coordinates into screen coordinates.
     * transform local coordinates into screen coordinates.
@@ -141,6 +148,7 @@ public final class CursorAnchorInfo implements Parcelable {
        mInsertionMarkerBaseline = source.readFloat();
        mInsertionMarkerBaseline = source.readFloat();
        mInsertionMarkerBottom = source.readFloat();
        mInsertionMarkerBottom = source.readFloat();
        mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader());
        mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader());
        mEditorBoundsInfo = source.readTypedObject(EditorBoundsInfo.CREATOR);
        mMatrixValues = source.createFloatArray();
        mMatrixValues = source.createFloatArray();
    }
    }


@@ -163,6 +171,7 @@ public final class CursorAnchorInfo implements Parcelable {
        dest.writeFloat(mInsertionMarkerBaseline);
        dest.writeFloat(mInsertionMarkerBaseline);
        dest.writeFloat(mInsertionMarkerBottom);
        dest.writeFloat(mInsertionMarkerBottom);
        dest.writeParcelable(mCharacterBoundsArray, flags);
        dest.writeParcelable(mCharacterBoundsArray, flags);
        dest.writeTypedObject(mEditorBoundsInfo, flags);
        dest.writeFloatArray(mMatrixValues);
        dest.writeFloatArray(mMatrixValues);
    }
    }


@@ -216,6 +225,10 @@ public final class CursorAnchorInfo implements Parcelable {
            return false;
            return false;
        }
        }


        if (!Objects.equals(mEditorBoundsInfo, that.mEditorBoundsInfo)) {
            return false;
        }

        // Following fields are (partially) covered by hashCode().
        // Following fields are (partially) covered by hashCode().


        if (mComposingTextStart != that.mComposingTextStart
        if (mComposingTextStart != that.mComposingTextStart
@@ -248,6 +261,7 @@ public final class CursorAnchorInfo implements Parcelable {
                + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
                + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
                + " mInsertionMarkerBottom=" + mInsertionMarkerBottom
                + " mInsertionMarkerBottom=" + mInsertionMarkerBottom
                + " mCharacterBoundsArray=" + Objects.toString(mCharacterBoundsArray)
                + " mCharacterBoundsArray=" + Objects.toString(mCharacterBoundsArray)
                + " mEditorBoundsInfo=" + mEditorBoundsInfo
                + " mMatrix=" + Arrays.toString(mMatrixValues)
                + " mMatrix=" + Arrays.toString(mMatrixValues)
                + "}";
                + "}";
    }
    }
@@ -266,6 +280,7 @@ public final class CursorAnchorInfo implements Parcelable {
        private float mInsertionMarkerBottom = Float.NaN;
        private float mInsertionMarkerBottom = Float.NaN;
        private int mInsertionMarkerFlags = 0;
        private int mInsertionMarkerFlags = 0;
        private SparseRectFArrayBuilder mCharacterBoundsArrayBuilder = null;
        private SparseRectFArrayBuilder mCharacterBoundsArrayBuilder = null;
        private EditorBoundsInfo mEditorBoundsInfo = null;
        private float[] mMatrixValues = null;
        private float[] mMatrixValues = null;
        private boolean mMatrixInitialized = false;
        private boolean mMatrixInitialized = false;


@@ -355,6 +370,17 @@ public final class CursorAnchorInfo implements Parcelable {
            return this;
            return this;
        }
        }


        /**
         * Sets the current editor related bounds.
         *
         * @param bounds {@link EditorBoundsInfo} in local coordinates.
         */
        @NonNull
        public Builder setEditorBoundsInfo(@Nullable EditorBoundsInfo bounds) {
            mEditorBoundsInfo = bounds;
            return this;
        }

        /**
        /**
         * Sets the matrix that transforms local coordinates into screen coordinates.
         * Sets the matrix that transforms local coordinates into screen coordinates.
         * @param matrix transformation matrix from local coordinates into screen coordinates. null
         * @param matrix transformation matrix from local coordinates into screen coordinates. null
@@ -410,6 +436,7 @@ public final class CursorAnchorInfo implements Parcelable {
            if (mCharacterBoundsArrayBuilder != null) {
            if (mCharacterBoundsArrayBuilder != null) {
                mCharacterBoundsArrayBuilder.reset();
                mCharacterBoundsArrayBuilder.reset();
            }
            }
            mEditorBoundsInfo = null;
        }
        }
    }
    }


@@ -425,6 +452,7 @@ public final class CursorAnchorInfo implements Parcelable {
        mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
        mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
        mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null
        mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null
                ? builder.mCharacterBoundsArrayBuilder.build() : null;
                ? builder.mCharacterBoundsArrayBuilder.build() : null;
        mEditorBoundsInfo = builder.mEditorBoundsInfo;
        mMatrixValues = new float[9];
        mMatrixValues = new float[9];
        if (builder.mMatrixInitialized) {
        if (builder.mMatrixInitialized) {
            System.arraycopy(builder.mMatrixValues, 0, mMatrixValues, 0, 9);
            System.arraycopy(builder.mMatrixValues, 0, mMatrixValues, 0, 9);
@@ -546,6 +574,14 @@ public final class CursorAnchorInfo implements Parcelable {
        return mCharacterBoundsArray.getFlags(index, 0);
        return mCharacterBoundsArray.getFlags(index, 0);
    }
    }


    /**
     * Returns {@link EditorBoundsInfo} editor related bounds.
     */
    @Nullable
    public EditorBoundsInfo getEditorBoundsInfo() {
        return mEditorBoundsInfo;
    }

    /**
    /**
     * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
     * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
     * matrix that is to be applied other positional data in this class.
     * matrix that is to be applied other positional data in this class.
+177 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.inputmethod;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.RectF;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Objects;

/**
 * Container of rectangular position related info for the Editor.
 */
public final class EditorBoundsInfo implements Parcelable {

    /**
     * Container of rectangular position of Editor in the current window.
     */
    private final RectF mEditorBounds;

    /**
     * Container of rectangular position of Editor with additional padding around for initiating
     * Stylus Handwriting in the current window.
     */
    private final RectF mHandwritingBounds;

    private final int mHashCode;

    private EditorBoundsInfo(@NonNull Parcel source) {
        mHashCode = source.readInt();
        mEditorBounds = source.readTypedObject(RectF.CREATOR);
        mHandwritingBounds = source.readTypedObject(RectF.CREATOR);
    }

    /**
     * Returns the bounds of the Editor in local coordinates.
     *
     * Screen coordinates can be obtained by transforming with the
     * {@link CursorAnchorInfo#getMatrix} of the containing {@code CursorAnchorInfo}.
     */
    @Nullable
    public RectF getEditorBounds() {
        return mEditorBounds;
    }

    /**
     * Returns the bounds of the area that should be considered for initiating stylus handwriting
     * in local coordinates.
     *
     * Screen coordinates can be obtained by transforming with the
     * {@link CursorAnchorInfo#getMatrix} of the containing {@code CursorAnchorInfo}.
     */
    @Nullable
    public RectF getHandwritingBounds() {
        return mHandwritingBounds;
    }

    @Override
    public int hashCode() {
        return mHashCode;
    }

    @Override
    public String toString() {
        return "EditorBoundsInfo{mEditorBounds=" + mEditorBounds
                + " mHandwritingBounds=" + mHandwritingBounds
                + "}";
    }

    @Override
    public boolean equals(@Nullable Object obj) {
        if (obj == null) {
            return false;
        }
        EditorBoundsInfo bounds;
        if (obj instanceof  EditorBoundsInfo) {
            bounds = (EditorBoundsInfo) obj;
        } else {
            return false;
        }
        return Objects.equals(bounds.mEditorBounds, mEditorBounds)
                && Objects.equals(bounds.mHandwritingBounds, mHandwritingBounds);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(mHashCode);
        dest.writeTypedObject(mEditorBounds, flags);
        dest.writeTypedObject(mHandwritingBounds, flags);
    }

    /**
     * Used to make this class parcelable.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<EditorBoundsInfo> CREATOR
            = new Parcelable.Creator<EditorBoundsInfo>() {
        @Override
        public EditorBoundsInfo createFromParcel(@NonNull Parcel source) {
            return new EditorBoundsInfo(source);
        }

        @Override
        public EditorBoundsInfo[] newArray(int size) {
            return new EditorBoundsInfo[size];
        }
    };

    /**
     * Builder for {@link CursorAnchorInfo}.
     */
    public static final class Builder {
        private RectF mEditorBounds = null;
        private RectF mHandwritingBounds = null;

        /**
         * Sets the bounding box of the current editor.
         *
         * @param bounds {@link RectF} in local coordinates.
         */
        @NonNull
        public EditorBoundsInfo.Builder setEditorBounds(@Nullable RectF bounds) {
            mEditorBounds = bounds;
            return this;
        }

        /**
         * Sets the current editor's bounds with padding for handwriting.
         *
         * @param bounds {@link RectF} in local coordinates.
         */
        @NonNull
        public EditorBoundsInfo.Builder setHandwritingBounds(@Nullable RectF bounds) {
            mHandwritingBounds = bounds;
            return this;
        }

        /**
         * Returns {@link EditorBoundsInfo} using parameters in this
         *   {@link EditorBoundsInfo.Builder}.
         */
        @NonNull
        public EditorBoundsInfo build() {
            return new EditorBoundsInfo(this);
        }
    }

    private EditorBoundsInfo(final EditorBoundsInfo.Builder builder) {
        mEditorBounds = builder.mEditorBounds;
        mHandwritingBounds = builder.mHandwritingBounds;

        int hash = Objects.hashCode(mEditorBounds);
        hash *= 31;
        hash += Objects.hashCode(mHandwritingBounds);
        mHashCode = hash;
    }
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -115,6 +115,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.LinearInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorBoundsInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.ExtractedTextRequest;
@@ -4570,6 +4571,12 @@ public class Editor {
            mTextView.getLocationOnScreen(mTmpIntOffset);
            mTextView.getLocationOnScreen(mTmpIntOffset);
            mViewToScreenMatrix.postTranslate(mTmpIntOffset[0], mTmpIntOffset[1]);
            mViewToScreenMatrix.postTranslate(mTmpIntOffset[0], mTmpIntOffset[1]);
            builder.setMatrix(mViewToScreenMatrix);
            builder.setMatrix(mViewToScreenMatrix);
            final RectF bounds = new RectF();
            mTextView.getBoundsOnScreen(bounds, false /* clipToParent */);
            EditorBoundsInfo.Builder boundsBuilder = new EditorBoundsInfo.Builder();
            //TODO(b/210039666): add Handwriting bounds once they're available.
            builder.setEditorBoundsInfo(
                    boundsBuilder.setEditorBounds(bounds).build());


            final float viewportToContentHorizontalOffset =
            final float viewportToContentHorizontalOffset =
                    mTextView.viewportToContentHorizontalOffset();
                    mTextView.viewportToContentHorizontalOffset();