Merge "Add EditorInfo#getInitialSurroundingText API"

This commit is contained in:
TreeHugger Robot
2021-01-08 02:56:18 +00:00
committed by Android (Google) Code Review
4 changed files with 240 additions and 154 deletions

View File

@@ -50464,6 +50464,7 @@ package android.view.inputmethod {
method public int describeContents();
method public void dump(android.util.Printer, String);
method @Nullable public CharSequence getInitialSelectedText(int);
method @Nullable public android.view.inputmethod.SurroundingText getInitialSurroundingText(@IntRange(from=0) int, @IntRange(from=0) int, int);
method @Nullable public CharSequence getInitialTextAfterCursor(int, int);
method @Nullable public CharSequence getInitialTextBeforeCursor(int, int);
method public final void makeCompatible(int);

View File

@@ -25,6 +25,7 @@ import static android.view.inputmethod.EditorInfoProto.PRIVATE_IME_OPTIONS;
import static android.view.inputmethod.EditorInfoProto.TARGET_INPUT_METHOD_USER_ID;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -36,7 +37,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.InputType;
import android.text.ParcelableSpan;
import android.text.TextUtils;
import android.util.Printer;
import android.util.proto.ProtoOutputStream;
@@ -44,6 +44,7 @@ import android.view.View;
import android.view.autofill.AutofillId;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -563,8 +564,9 @@ public class EditorInfo implements InputType, Parcelable {
@VisibleForTesting
static final int MAX_INITIAL_SELECTION_LENGTH = MEMORY_EFFICIENT_TEXT_LENGTH / 2;
@NonNull
private InitialSurroundingText mInitialSurroundingText = new InitialSurroundingText();
@Nullable
private SurroundingText mInitialSurroundingText = null;
/**
* Editors may use this method to provide initial input text to IMEs. As the surrounding text
@@ -607,6 +609,12 @@ public class EditorInfo implements InputType, Parcelable {
public void setInitialSurroundingSubText(@NonNull CharSequence subText, int subTextStart) {
Objects.requireNonNull(subText);
// For privacy protection reason, we don't carry password inputs to IMEs.
if (isPasswordInputType(inputType)) {
mInitialSurroundingText = null;
return;
}
// Swap selection start and end if necessary.
final int subTextSelStart = initialSelStart > initialSelEnd
? initialSelEnd - subTextStart : initialSelStart - subTextStart;
@@ -616,23 +624,17 @@ public class EditorInfo implements InputType, Parcelable {
final int subTextLength = subText.length();
// Unknown or invalid selection.
if (subTextStart < 0 || subTextSelStart < 0 || subTextSelEnd > subTextLength) {
mInitialSurroundingText = new InitialSurroundingText();
return;
}
// For privacy protection reason, we don't carry password inputs to IMEs.
if (isPasswordInputType(inputType)) {
mInitialSurroundingText = new InitialSurroundingText();
mInitialSurroundingText = null;
return;
}
if (subTextLength <= MEMORY_EFFICIENT_TEXT_LENGTH) {
mInitialSurroundingText = new InitialSurroundingText(subText, subTextSelStart,
subTextSelEnd);
mInitialSurroundingText = new SurroundingText(subText, subTextSelStart,
subTextSelEnd, subTextStart);
return;
}
trimLongSurroundingText(subText, subTextSelStart, subTextSelEnd);
trimLongSurroundingText(subText, subTextSelStart, subTextSelEnd, subTextStart);
}
/**
@@ -651,8 +653,10 @@ public class EditorInfo implements InputType, Parcelable {
* @param subText The long text that needs to be trimmed.
* @param selStart The text offset of the start of the selection.
* @param selEnd The text offset of the end of the selection
* @param subTextStart The position that the input text got trimmed.
*/
private void trimLongSurroundingText(CharSequence subText, int selStart, int selEnd) {
private void trimLongSurroundingText(CharSequence subText, int selStart, int selEnd,
int subTextStart) {
final int sourceSelLength = selEnd - selStart;
// When the selected text is too long, drop it.
final int newSelLength = (sourceSelLength > MAX_INITIAL_SELECTION_LENGTH)
@@ -702,10 +706,13 @@ public class EditorInfo implements InputType, Parcelable {
// obj.
newBeforeCursorHead = 0;
final int newSelHead = newBeforeCursorHead + newBeforeCursorLength;
mInitialSurroundingText = new InitialSurroundingText(
newInitialSurroundingText, newSelHead, newSelHead + newSelLength);
final int newOffset = subTextStart + selStart - newSelHead;
mInitialSurroundingText = new SurroundingText(
newInitialSurroundingText, newSelHead, newSelHead + newSelLength,
newOffset);
}
/**
* Get <var>length</var> characters of text before the current cursor position. May be
* {@code null} when the protocol is not supported.
@@ -720,7 +727,17 @@ public class EditorInfo implements InputType, Parcelable {
*/
@Nullable
public CharSequence getInitialTextBeforeCursor(int length, int flags) {
return mInitialSurroundingText.getInitialTextBeforeCursor(length, flags);
if (mInitialSurroundingText == null) {
return null;
}
int selStart = Math.min(mInitialSurroundingText.getSelectionStart(),
mInitialSurroundingText.getSelectionEnd());
int n = Math.min(length, selStart);
return ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mInitialSurroundingText.getText().subSequence(selStart - n, selStart)
: TextUtils.substring(mInitialSurroundingText.getText(), selStart - n,
selStart);
}
/**
@@ -735,6 +752,10 @@ public class EditorInfo implements InputType, Parcelable {
*/
@Nullable
public CharSequence getInitialSelectedText(int flags) {
if (mInitialSurroundingText == null) {
return null;
}
// Swap selection start and end if necessary.
final int correctedTextSelStart = initialSelStart > initialSelEnd
? initialSelEnd : initialSelStart;
@@ -742,11 +763,21 @@ public class EditorInfo implements InputType, Parcelable {
? initialSelStart : initialSelEnd;
final int sourceSelLength = correctedTextSelEnd - correctedTextSelStart;
if (initialSelStart < 0 || initialSelEnd < 0
|| mInitialSurroundingText.getSelectionLength() != sourceSelLength) {
int selStart = mInitialSurroundingText.getSelectionStart();
int selEnd = mInitialSurroundingText.getSelectionEnd();
if (selStart > selEnd) {
int tmp = selStart;
selStart = selEnd;
selEnd = tmp;
}
final int selLength = selEnd - selStart;
if (initialSelStart < 0 || initialSelEnd < 0 || selLength != sourceSelLength) {
return null;
}
return mInitialSurroundingText.getInitialSelectedText(flags);
return ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mInitialSurroundingText.getText().subSequence(selStart, selEnd)
: TextUtils.substring(mInitialSurroundingText.getText(), selStart, selEnd);
}
/**
@@ -763,7 +794,79 @@ public class EditorInfo implements InputType, Parcelable {
*/
@Nullable
public CharSequence getInitialTextAfterCursor(int length, int flags) {
return mInitialSurroundingText.getInitialTextAfterCursor(length, flags);
if (mInitialSurroundingText == null) {
return null;
}
int surroundingTextLength = mInitialSurroundingText.getText().length();
int selEnd = Math.max(mInitialSurroundingText.getSelectionStart(),
mInitialSurroundingText.getSelectionEnd());
int n = Math.min(length, surroundingTextLength - selEnd);
return ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mInitialSurroundingText.getText().subSequence(selEnd, selEnd + n)
: TextUtils.substring(mInitialSurroundingText.getText(), selEnd, selEnd + n);
}
/**
* Gets the surrounding text around the current cursor, with <var>beforeLength</var> characters
* of text before the cursor (start of the selection), <var>afterLength</var> characters of text
* after the cursor (end of the selection), and all of the selected text.
*
* <p>The initial surrounding text for return could be trimmed if oversize. Fundamental trimming
* rules are:</p>
* <ul>
* <li>The text before the cursor is the most important information to IMEs.</li>
* <li>The text after the cursor is the second important information to IMEs.</li>
* <li>The selected text is the least important information but it shall NEVER be truncated.
* When it is too long, just drop it.</li>
* </ul>
*
* <p>For example, the subText can be viewed as TextBeforeCursor + Selection + TextAfterCursor.
* The result could be:</p>
* <ol>
* <li>(maybeTrimmedAtHead)TextBeforeCursor + Selection
* + TextAfterCursor(maybeTrimmedAtTail)</li>
* <li>(maybeTrimmedAtHead)TextBeforeCursor + TextAfterCursor(maybeTrimmedAtTail)</li>
* </ol>
*
* @param beforeLength The expected length of the text before the cursor.
* @param afterLength The expected length of the text after the cursor.
* @param flags Supplies additional options controlling how the text is returned. May be either
* {@code 0} or {@link InputConnection#GET_TEXT_WITH_STYLES}.
* @return an {@link android.view.inputmethod.SurroundingText} object describing the surrounding
* text and state of selection, or {@code null} if the editor or system could not support this
* protocol.
* @throws IllegalArgumentException if {@code beforeLength} or {@code afterLength} is negative.
*/
@Nullable
public SurroundingText getInitialSurroundingText(
@IntRange(from = 0) int beforeLength, @IntRange(from = 0) int afterLength,
@InputConnection.GetTextType int flags) {
Preconditions.checkArgumentNonnegative(beforeLength);
Preconditions.checkArgumentNonnegative(afterLength);
if (mInitialSurroundingText == null) {
return null;
}
int length = mInitialSurroundingText.getText().length();
int selStart = mInitialSurroundingText.getSelectionStart();
int selEnd = mInitialSurroundingText.getSelectionEnd();
if (selStart > selEnd) {
int tmp = selStart;
selStart = selEnd;
selEnd = tmp;
}
int before = Math.min(beforeLength, selStart);
int after = Math.min(selEnd + afterLength, length);
int offset = selStart - before;
CharSequence newText = ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mInitialSurroundingText.getText().subSequence(offset, after)
: TextUtils.substring(mInitialSurroundingText.getText(), offset, after);
int newSelEnd = Math.min(selEnd - offset, length);
return new SurroundingText(newText, before, newSelEnd,
mInitialSurroundingText.getOffset() + offset);
}
private static boolean isCutOnSurrogate(CharSequence sourceText, int cutPosition,
@@ -893,7 +996,10 @@ public class EditorInfo implements InputType, Parcelable {
dest.writeInt(fieldId);
dest.writeString(fieldName);
dest.writeBundle(extras);
mInitialSurroundingText.writeToParcel(dest, flags);
dest.writeBoolean(mInitialSurroundingText != null);
if (mInitialSurroundingText != null) {
mInitialSurroundingText.writeToParcel(dest, flags);
}
if (hintLocales != null) {
hintLocales.writeToParcel(dest, flags);
} else {
@@ -925,9 +1031,11 @@ public class EditorInfo implements InputType, Parcelable {
res.fieldId = source.readInt();
res.fieldName = source.readString();
res.extras = source.readBundle();
InitialSurroundingText initialSurroundingText =
InitialSurroundingText.CREATOR.createFromParcel(source);
res.mInitialSurroundingText = initialSurroundingText;
boolean hasInitialSurroundingText = source.readBoolean();
if (hasInitialSurroundingText) {
res.mInitialSurroundingText =
SurroundingText.CREATOR.createFromParcel(source);
}
LocaleList hintLocales = LocaleList.CREATOR.createFromParcel(source);
res.hintLocales = hintLocales.isEmpty() ? null : hintLocales;
res.contentMimeTypes = source.readStringArray();
@@ -943,120 +1051,4 @@ public class EditorInfo implements InputType, Parcelable {
public int describeContents() {
return 0;
}
static final class InitialSurroundingText implements Parcelable {
@Nullable final CharSequence mSurroundingText;
final int mSelectionHead;
final int mSelectionEnd;
InitialSurroundingText() {
mSurroundingText = null;
mSelectionHead = 0;
mSelectionEnd = 0;
}
InitialSurroundingText(@Nullable CharSequence surroundingText, int selectionHead,
int selectionEnd) {
// Copy the original text (without NoCopySpan) in case the original text is updated
// later.
mSurroundingText = copyWithParcelableSpans(surroundingText);
mSelectionHead = selectionHead;
mSelectionEnd = selectionEnd;
}
@Nullable
private CharSequence getInitialTextBeforeCursor(int n, int flags) {
if (mSurroundingText == null) {
return null;
}
final int length = Math.min(n, mSelectionHead);
return ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mSurroundingText.subSequence(mSelectionHead - length, mSelectionHead)
: TextUtils.substring(mSurroundingText, mSelectionHead - length,
mSelectionHead);
}
@Nullable
private CharSequence getInitialSelectedText(int flags) {
if (mSurroundingText == null) {
return null;
}
return ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mSurroundingText.subSequence(mSelectionHead, mSelectionEnd)
: TextUtils.substring(mSurroundingText, mSelectionHead, mSelectionEnd);
}
@Nullable
private CharSequence getInitialTextAfterCursor(int n, int flags) {
if (mSurroundingText == null) {
return null;
}
final int length = Math.min(n, mSurroundingText.length() - mSelectionEnd);
return ((flags & InputConnection.GET_TEXT_WITH_STYLES) != 0)
? mSurroundingText.subSequence(mSelectionEnd, mSelectionEnd + length)
: TextUtils.substring(mSurroundingText, mSelectionEnd, mSelectionEnd + length);
}
private int getSelectionLength() {
return mSelectionEnd - mSelectionHead;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
TextUtils.writeToParcel(mSurroundingText, dest, flags);
dest.writeInt(mSelectionHead);
dest.writeInt(mSelectionEnd);
}
public static final @android.annotation.NonNull Parcelable.Creator<InitialSurroundingText>
CREATOR = new Parcelable.Creator<InitialSurroundingText>() {
@Override
public InitialSurroundingText createFromParcel(Parcel source) {
final CharSequence initialText =
TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
final int selectionHead = source.readInt();
final int selectionEnd = source.readInt();
return new InitialSurroundingText(initialText, selectionHead, selectionEnd);
}
@Override
public InitialSurroundingText[] newArray(int size) {
return new InitialSurroundingText[size];
}
};
/**
* Create a copy of the given {@link CharSequence} object, with completely copy
* {@link ParcelableSpan} instances.
*
* @param source the original {@link CharSequence} to be copied.
* @return the copied {@link CharSequence}. {@code null} if {@code source} is {@code null}.
*/
@Nullable
private static CharSequence copyWithParcelableSpans(@Nullable CharSequence source) {
if (source == null) {
return null;
}
Parcel parcel = null;
try {
parcel = Parcel.obtain();
TextUtils.writeToParcel(source, parcel, /* parcelableFlags= */ 0);
parcel.setDataPosition(0);
return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
} finally {
if (parcel != null) {
parcel.recycle();
}
}
}
}
}
}

View File

@@ -18,6 +18,7 @@ package android.view.inputmethod;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -74,7 +75,7 @@ public final class SurroundingText implements Parcelable {
public SurroundingText(@NonNull final CharSequence text,
@IntRange(from = 0) int selectionStart, @IntRange(from = 0) int selectionEnd,
@IntRange(from = -1) int offset) {
mText = text;
mText = copyWithParcelableSpans(text);
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mOffset = offset;
@@ -155,4 +156,29 @@ public final class SurroundingText implements Parcelable {
return new SurroundingText[size];
}
};
/**
* Create a copy of the given {@link CharSequence} object, with completely copy
* {@link ParcelableSpan} instances.
*
* @param source the original {@link CharSequence} to be copied.
* @return the copied {@link CharSequence}. {@code null} if {@code source} is {@code null}.
*/
@Nullable
private static CharSequence copyWithParcelableSpans(@Nullable CharSequence source) {
if (source == null) {
return null;
}
Parcel parcel = null;
try {
parcel = Parcel.obtain();
TextUtils.writeToParcel(source, parcel, /* parcelableFlags= */ 0);
parcel.setDataPosition(0);
return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
} finally {
if (parcel != null) {
parcel.recycle();
}
}
}
}

View File

@@ -109,11 +109,15 @@ public class EditorInfoTest {
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
final int expectedTextBeforeCursorLength = 0;
final int expectedTextAfterCursorLength = testText.length();
final SurroundingText expectedSurroundingText =
new SurroundingText(testText, editorInfo.initialSelStart,
editorInfo.initialSelEnd, 0);
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
expectedTextAfterCursorLength);
expectedTextAfterCursorLength, expectedSurroundingText);
}
@Test
@@ -125,11 +129,14 @@ public class EditorInfoTest {
editorInfo.initialSelEnd = testText.length();
final int expectedTextBeforeCursorLength = testText.length();
final int expectedTextAfterCursorLength = 0;
final SurroundingText expectedSurroundingText =
new SurroundingText(testText, editorInfo.initialSelStart,
editorInfo.initialSelEnd, 0);
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
expectedTextAfterCursorLength);
expectedTextAfterCursorLength, expectedSurroundingText);
}
@Test
@@ -141,11 +148,14 @@ public class EditorInfoTest {
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
final int expectedTextBeforeCursorLength = editorInfo.initialSelStart;
final int expectedTextAfterCursorLength = testText.length() - editorInfo.initialSelEnd;
final SurroundingText expectedSurroundingText =
new SurroundingText(testText, editorInfo.initialSelStart,
editorInfo.initialSelEnd, 0);
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
expectedTextAfterCursorLength);
expectedTextAfterCursorLength, expectedSurroundingText);
}
@Test
@@ -158,11 +168,14 @@ public class EditorInfoTest {
final int expectedTextBeforeCursorLength = testText.length() / 2;
final int expectedTextAfterCursorLength = testText.length() - testText.length() / 2
- selectionLength;
final SurroundingText expectedSurroundingText =
new SurroundingText(testText,
editorInfo.initialSelEnd,
editorInfo.initialSelStart , 0);
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
expectedTextAfterCursorLength);
expectedTextAfterCursorLength, expectedSurroundingText);
}
@Test
@@ -174,9 +187,10 @@ public class EditorInfoTest {
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo,
/* expectBeforeCursorLength= */null,
/* expectSelectionLength= */null,
/* expectAfterCursorLength= */null);
/* expectBeforeCursorLength= */ null,
/* expectSelectionLength= */ null,
/* expectAfterCursorLength= */ null,
/* expectSurroundingText= */ null);
}
@Test
@@ -190,11 +204,23 @@ public class EditorInfoTest {
(int) (0.8 * (EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH - selectionLength)));
final int expectedTextAfterCursorLength = EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH
- expectedTextBeforeCursorLength - selectionLength;
final int offset = editorInfo.initialSelStart - expectedTextBeforeCursorLength;
final CharSequence beforeCursor = testText.subSequence(
offset, offset + expectedTextBeforeCursorLength);
final CharSequence afterCursor = testText.subSequence(editorInfo.initialSelEnd,
editorInfo.initialSelEnd + expectedTextAfterCursorLength);
final CharSequence selectedText = testText.subSequence(editorInfo.initialSelStart,
editorInfo.initialSelEnd);
final SurroundingText expectedSurroundingText =
new SurroundingText(TextUtils.concat(beforeCursor, selectedText, afterCursor),
expectedTextBeforeCursorLength,
expectedTextBeforeCursorLength + selectionLength, offset);
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
expectedTextAfterCursorLength);
expectedTextAfterCursorLength, expectedSurroundingText);
}
@Test
@@ -207,11 +233,22 @@ public class EditorInfoTest {
final int expectedTextBeforeCursorLength = Math.min(editorInfo.initialSelStart,
(int) (0.8 * EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH));
final int expectedTextAfterCursorLength = testText.length() - editorInfo.initialSelEnd;
final CharSequence before = testText.subSequence(
editorInfo.initialSelStart - expectedTextBeforeCursorLength,
expectedTextBeforeCursorLength);
final CharSequence after = testText.subSequence(editorInfo.initialSelEnd,
editorInfo.initialSelEnd + expectedTextAfterCursorLength);
final SurroundingText expectedSurroundingText =
new SurroundingText(TextUtils.concat(before, after),
expectedTextBeforeCursorLength,
expectedTextBeforeCursorLength,
editorInfo.initialSelStart - expectedTextBeforeCursorLength);
editorInfo.setInitialSurroundingText(testText);
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength,
/* expectSelectionLength= */null, expectedTextAfterCursorLength);
/* expectSelectionLength= */null, expectedTextAfterCursorLength,
expectedSurroundingText);
}
@Test
@@ -269,6 +306,19 @@ public class EditorInfoTest {
InputConnection.GET_TEXT_WITH_STYLES),
targetEditorInfo.getInitialTextAfterCursor(LONG_EXP_TEXT_LENGTH,
InputConnection.GET_TEXT_WITH_STYLES)));
final SurroundingText sourceSurroundingText = sourceEditorInfo.getInitialSurroundingText(
LONG_EXP_TEXT_LENGTH, LONG_EXP_TEXT_LENGTH, InputConnection.GET_TEXT_WITH_STYLES);
final SurroundingText targetSurroundingText = targetEditorInfo.getInitialSurroundingText(
LONG_EXP_TEXT_LENGTH, LONG_EXP_TEXT_LENGTH, InputConnection.GET_TEXT_WITH_STYLES);
assertTrue(TextUtils.equals(sourceSurroundingText.getText(),
targetSurroundingText.getText()));
assertEquals(sourceSurroundingText.getSelectionStart(),
targetSurroundingText.getSelectionStart());
assertEquals(sourceSurroundingText.getSelectionEnd(),
targetSurroundingText.getSelectionEnd());
assertEquals(sourceSurroundingText.getOffset(), targetSurroundingText.getOffset());
}
@Test
@@ -338,7 +388,8 @@ public class EditorInfoTest {
private static void assertExpectedTextLength(EditorInfo editorInfo,
@Nullable Integer expectBeforeCursorLength, @Nullable Integer expectSelectionLength,
@Nullable Integer expectAfterCursorLength) {
@Nullable Integer expectAfterCursorLength,
@Nullable SurroundingText expectSurroundingText) {
final CharSequence textBeforeCursor =
editorInfo.getInitialTextBeforeCursor(LONG_EXP_TEXT_LENGTH,
InputConnection.GET_TEXT_WITH_STYLES);
@@ -347,6 +398,10 @@ public class EditorInfoTest {
final CharSequence textAfterCursor =
editorInfo.getInitialTextAfterCursor(LONG_EXP_TEXT_LENGTH,
InputConnection.GET_TEXT_WITH_STYLES);
final SurroundingText surroundingText = editorInfo.getInitialSurroundingText(
LONG_EXP_TEXT_LENGTH,
LONG_EXP_TEXT_LENGTH,
InputConnection.GET_TEXT_WITH_STYLES);
if (expectBeforeCursorLength == null) {
assertNull(textBeforeCursor);
@@ -365,6 +420,18 @@ public class EditorInfoTest {
} else {
assertEquals(expectAfterCursorLength.intValue(), textAfterCursor.length());
}
if (expectSurroundingText == null) {
assertNull(surroundingText);
} else {
assertTrue(TextUtils.equals(
expectSurroundingText.getText(), surroundingText.getText()));
assertEquals(expectSurroundingText.getSelectionStart(),
surroundingText.getSelectionStart());
assertEquals(expectSurroundingText.getSelectionEnd(),
surroundingText.getSelectionEnd());
assertEquals(expectSurroundingText.getOffset(), surroundingText.getOffset());
}
}
private static CharSequence createTestText(int surroundingLength) {