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

Commit a719be69 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

am 15e35270: am 5e449276: am f2474d33: Merge "Implement better handling of...

am 15e35270: am 5e449276: am f2474d33: Merge "Implement better handling of text in assist." into mnc-dev

* commit '15e35270':
  Implement better handling of text in assist.
parents 9a7c5627 15e35270
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5822,6 +5822,8 @@ package android.app.assist {
    method public java.lang.CharSequence getText();
    method public int getTextBackgroundColor();
    method public int getTextColor();
    method public int[] getTextLineBaselines();
    method public int[] getTextLineCharOffsets();
    method public int getTextSelectionEnd();
    method public int getTextSelectionStart();
    method public float getTextSize();
@@ -36953,6 +36955,7 @@ package android.view {
    method public abstract void setSelected(boolean);
    method public abstract void setText(java.lang.CharSequence);
    method public abstract void setText(java.lang.CharSequence, int, int);
    method public abstract void setTextLines(int[], int[]);
    method public abstract void setTextStyle(float, int, int, int);
    method public abstract void setTransformation(android.graphics.Matrix);
    method public abstract void setVisibility(int);
+3 −0
Original line number Diff line number Diff line
@@ -5954,6 +5954,8 @@ package android.app.assist {
    method public java.lang.CharSequence getText();
    method public int getTextBackgroundColor();
    method public int getTextColor();
    method public int[] getTextLineBaselines();
    method public int[] getTextLineCharOffsets();
    method public int getTextSelectionEnd();
    method public int getTextSelectionStart();
    method public float getTextSize();
@@ -39243,6 +39245,7 @@ package android.view {
    method public abstract void setSelected(boolean);
    method public abstract void setText(java.lang.CharSequence);
    method public abstract void setText(java.lang.CharSequence, int, int);
    method public abstract void setTextLines(int[], int[]);
    method public abstract void setTextStyle(float, int, int, int);
    method public abstract void setTransformation(android.graphics.Matrix);
    method public abstract void setVisibility(int);
+68 −21
Original line number Diff line number Diff line
@@ -61,39 +61,55 @@ public class AssistStructure implements Parcelable {

    final static class ViewNodeText {
        CharSequence mText;
        int mTextSelectionStart;
        int mTextSelectionEnd;
        int mTextColor;
        int mTextBackgroundColor;
        float mTextSize;
        int mTextStyle;
        int mTextColor = ViewNode.TEXT_COLOR_UNDEFINED;
        int mTextBackgroundColor = ViewNode.TEXT_COLOR_UNDEFINED;
        int mTextSelectionStart;
        int mTextSelectionEnd;
        int[] mLineCharOffsets;
        int[] mLineBaselines;
        String mHint;

        ViewNodeText() {
        }

        ViewNodeText(Parcel in) {
        boolean isSimple() {
            return mTextBackgroundColor == ViewNode.TEXT_COLOR_UNDEFINED
                    && mTextSelectionStart == 0 && mTextSelectionEnd == 0
                    && mLineCharOffsets == null && mLineBaselines == null && mHint == null;
        }

        ViewNodeText(Parcel in, boolean simple) {
            mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            mTextSelectionStart = in.readInt();
            mTextSelectionEnd = in.readInt();
            mTextColor = in.readInt();
            mTextBackgroundColor = in.readInt();
            mTextSize = in.readFloat();
            mTextStyle = in.readInt();
            mTextColor = in.readInt();
            if (!simple) {
                mTextBackgroundColor = in.readInt();
                mTextSelectionStart = in.readInt();
                mTextSelectionEnd = in.readInt();
                mLineCharOffsets = in.createIntArray();
                mLineBaselines = in.createIntArray();
                mHint = in.readString();
            }
        }

        void writeToParcel(Parcel out) {
        void writeToParcel(Parcel out, boolean simple) {
            TextUtils.writeToParcel(mText, out, 0);
            out.writeInt(mTextSelectionStart);
            out.writeInt(mTextSelectionEnd);
            out.writeInt(mTextColor);
            out.writeInt(mTextBackgroundColor);
            out.writeFloat(mTextSize);
            out.writeInt(mTextStyle);
            out.writeInt(mTextColor);
            if (!simple) {
                out.writeInt(mTextBackgroundColor);
                out.writeInt(mTextSelectionStart);
                out.writeInt(mTextSelectionEnd);
                out.writeIntArray(mLineCharOffsets);
                out.writeIntArray(mLineBaselines);
                out.writeString(mHint);
            }
        }
    }

    /**
     * Describes a window in the assist data.
@@ -252,9 +268,10 @@ public class AssistStructure implements Parcelable {
        static final int FLAGS_HAS_LARGE_COORDS = 0x04000000;
        static final int FLAGS_HAS_CONTENT_DESCRIPTION = 0x02000000;
        static final int FLAGS_HAS_TEXT = 0x01000000;
        static final int FLAGS_HAS_EXTRAS = 0x00800000;
        static final int FLAGS_HAS_ID = 0x00400000;
        static final int FLAGS_HAS_CHILDREN = 0x00200000;
        static final int FLAGS_HAS_COMPLEX_TEXT = 0x00800000;
        static final int FLAGS_HAS_EXTRAS = 0x00400000;
        static final int FLAGS_HAS_ID = 0x00200000;
        static final int FLAGS_HAS_CHILDREN = 0x00100000;
        static final int FLAGS_ALL_CONTROL = 0xfff00000;

        int mFlags;
@@ -316,7 +333,7 @@ public class AssistStructure implements Parcelable {
                mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            }
            if ((flags&FLAGS_HAS_TEXT) != 0) {
                mText = new ViewNodeText(in);
                mText = new ViewNodeText(in, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
            }
            if ((flags&FLAGS_HAS_EXTRAS) != 0) {
                mExtras = in.readBundle();
@@ -356,6 +373,9 @@ public class AssistStructure implements Parcelable {
            }
            if (mText != null) {
                flags |= FLAGS_HAS_TEXT;
                if (!mText.isSimple()) {
                    flags |= FLAGS_HAS_COMPLEX_TEXT;
                }
            }
            if (mExtras != null) {
                flags |= FLAGS_HAS_EXTRAS;
@@ -403,7 +423,7 @@ public class AssistStructure implements Parcelable {
                TextUtils.writeToParcel(mContentDescription, out, 0);
            }
            if ((flags&FLAGS_HAS_TEXT) != 0) {
                mText.writeToParcel(out);
                mText.writeToParcel(out, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
            }
            if ((flags&FLAGS_HAS_EXTRAS) != 0) {
                out.writeBundle(mExtras);
@@ -702,6 +722,26 @@ public class AssistStructure implements Parcelable {
            return mText != null ? mText.mTextStyle : 0;
        }

        /**
         * Return per-line offsets into the text returned by {@link #getText()}.  Each entry
         * in the array is a formatted line of text, and the value it contains is the offset
         * into the text string where that line starts.  May return null if there is no line
         * information.
         */
        public int[] getTextLineCharOffsets() {
            return mText != null ? mText.mLineCharOffsets : null;
        }

        /**
         * Return per-line baselines into the text returned by {@link #getText()}.  Each entry
         * in the array is a formatted line of text, and the value it contains is the baseline
         * where that text appears in the view.  May return null if there is no line
         * information.
         */
        public int[] getTextLineBaselines() {
            return mText != null ? mText.mLineBaselines : null;
        }

        /**
         * Return additional hint text associated with the node; this is typically used with
         * a node that takes user input, describing to the user what the input means.
@@ -900,6 +940,13 @@ public class AssistStructure implements Parcelable {
            t.mTextStyle = style;
        }

        @Override
        public void setTextLines(int[] charOffsets, int[] baselines) {
            ViewNodeText t = getNodeText();
            t.mLineCharOffsets = charOffsets;
            t.mLineBaselines = baselines;
        }

        @Override
        public void setHint(CharSequence hint) {
            getNodeText().mHint = hint != null ? hint.toString() : null;
+11 −0
Original line number Diff line number Diff line
@@ -177,6 +177,17 @@ public abstract class ViewStructure {
     */
    public abstract void setTextStyle(float size, int fgColor, int bgColor, int style);

    /**
     * Set line information for test that was previously supplied through
     * {@link #setText(CharSequence)}.  This provides the line breaking of the text as it
     * is shown on screen.  This function takes ownership of the provided arrays; you should
     * not make further modification to them.
     *
     * @param charOffsets The offset in to {@link #setText} where a line starts.
     * @param baselines The baseline where the line is drawn on screen.
     */
    public abstract void setTextLines(int[] charOffsets, int[] baselines);

    /**
     * Set optional hint text associated with this view; this is for example the text that is
     * shown by an EditText when it is empty to indicate to the user the kind of text to input.
+96 −13
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.ExtractEditText;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcel;
@@ -116,6 +115,7 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewStructure;
import android.view.ViewConfiguration;
import android.view.ViewDebug;
@@ -5823,6 +5823,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            return super.getBaseline();
        }

        return getBaselineOffset() + mLayout.getLineBaseline(0);
    }

    int getBaselineOffset() {
        int voffset = 0;
        if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
            voffset = getVerticalOffset(true);
@@ -5832,7 +5836,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            voffset -= getOpticalInsets().top;
        }

        return getExtendedPaddingTop() + voffset + mLayout.getLineBaseline(0);
        return getExtendedPaddingTop() + voffset;
    }

    /**
@@ -8767,7 +8771,79 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        final boolean isPassword = hasPasswordTransformationMethod()
                || isPasswordInputType(getInputType());
        if (!isPassword) {
            if (mLayout == null) {
                assumeLayout();
            }
            Layout layout = mLayout;
            final int lineCount = layout.getLineCount();
            if (lineCount <= 1) {
                // Simple case: this is a single line.
                structure.setText(getText(), getSelectionStart(), getSelectionEnd());
            } else {
                // Complex case: multi-line, could be scrolled or within a scroll container
                // so some lines are not visible.
                final int[] tmpCords = new int[2];
                getLocationInWindow(tmpCords);
                final int topWindowLocation = tmpCords[1];
                View root = this;
                ViewParent viewParent = getParent();
                while (viewParent instanceof View) {
                    root = (View) viewParent;
                    viewParent = root.getParent();
                }
                final int windowHeight = root.getHeight();
                final int topLine;
                final int bottomLine;
                if (topWindowLocation >= 0) {
                    // The top of the view is fully within its window; start text at line 0.
                    topLine = getLineAtCoordinateUnclamped(0);
                    bottomLine = getLineAtCoordinateUnclamped(windowHeight-1);
                } else {
                    // The top of hte window has scrolled off the top of the window; figure out
                    // the starting line for this.
                    topLine = getLineAtCoordinateUnclamped(-topWindowLocation);
                    bottomLine = getLineAtCoordinateUnclamped(windowHeight-1-topWindowLocation);
                }
                // We want to return some contextual lines above/below the lines that are
                // actually visible.
                int expandedTopLine = topLine - (bottomLine-topLine)/2;
                if (expandedTopLine < 0) {
                    expandedTopLine = 0;
                }
                int expandedBottomLine = bottomLine + (bottomLine-topLine)/2;
                if (expandedBottomLine >= lineCount) {
                    expandedBottomLine = lineCount-1;
                }
                // Convert lines into character offsets.
                int expandedTopChar = layout.getLineStart(expandedTopLine);
                int expandedBottomChar = layout.getLineEnd(expandedBottomLine);
                // Take into account selection -- if there is a selection, we need to expand
                // the text we are returning to include that selection.
                final int selStart = getSelectionStart();
                final int selEnd = getSelectionEnd();
                if (selStart < selEnd) {
                    if (selStart < expandedTopChar) {
                        expandedTopChar = selStart;
                    }
                    if (selEnd > expandedBottomChar) {
                        expandedBottomChar = selEnd;
                    }
                }
                // Get the text and trim it to the range we are reporting.
                CharSequence text = getText();
                if (expandedTopChar > 0 || expandedBottomChar < text.length()) {
                    text = text.subSequence(expandedTopChar, expandedBottomChar);
                }
                structure.setText(text, selStart-expandedTopChar, selEnd-expandedTopChar);
                final int[] lineOffsets = new int[bottomLine-topLine+1];
                final int[] lineBaselines = new int[bottomLine-topLine+1];
                final int baselineOffset = getBaselineOffset();
                for (int i=topLine; i<=bottomLine; i++) {
                    lineOffsets[i-topLine] = layout.getLineStart(i);
                    lineBaselines[i-topLine] = layout.getLineBaseline(i) + baselineOffset;
                }
                structure.setTextLines(lineOffsets, lineBaselines);
            }

            // Extract style information that applies to the TextView as a whole.
            int style = 0;
@@ -9200,24 +9276,25 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     * If provided, this ActionMode.Callback will be used to create the ActionMode when text
     * selection is initiated in this View.
     *
     * The standard implementation populates the menu with a subset of Select All, Cut, Copy,
     * <p>The standard implementation populates the menu with a subset of Select All, Cut, Copy,
     * Paste, Replace and Share actions, depending on what this View supports.
     *
     * A custom implementation can add new entries in the default menu in its
     * {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
     * default actions can also be removed from the menu using
     * <p>A custom implementation can add new entries in the default menu in its
     * {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, android.view.Menu)}
     * method. The default actions can also be removed from the menu using
     * {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll},
     * {@link android.R.id#cut}, {@link android.R.id#copy}, {@link android.R.id#paste},
     * {@link android.R.id#replaceText} or {@link android.R.id#shareText} ids as parameters.
     *
     * Returning false from
     * {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
     * the action mode from being started.
     * <p>Returning false from
     * {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, android.view.Menu)}
     * will prevent the action mode from being started.
     *
     * Action click events should be handled by the custom implementation of
     * {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
     * <p>Action click events should be handled by the custom implementation of
     * {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode,
     * android.view.MenuItem)}.
     *
     * Note that text selection mode is not started when a TextView receives focus and the
     * <p>Note that text selection mode is not started when a TextView receives focus and the
     * {@link android.R.attr#selectAllOnFocus} flag has been set. The content is highlighted in
     * that case, to allow for quick replacement.
     */
@@ -9448,6 +9525,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return getLayout().getLineForVertical((int) y);
    }

    int getLineAtCoordinateUnclamped(float y) {
        y -= getTotalPaddingTop();
        y += getScrollY();
        return getLayout().getLineForVertical((int) y);
    }

    int getOffsetAtCoordinate(int line, float x) {
        x = convertToLocalHorizontalCoordinate(x);
        return getLayout().getOffsetForHorizontal(line, x);
Loading