diff --git a/core/api/current.txt b/core/api/current.txt
index 29d4915a4953a..812ce175db503 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -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);
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 1cf25a77fa38a..2df75f6570db1 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -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 length 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 beforeLength characters
+ * of text before the cursor (start of the selection), afterLength characters of text
+ * after the cursor (end of the selection), and all of the selected text.
+ *
+ *
The initial surrounding text for return could be trimmed if oversize. Fundamental trimming
+ * rules are:
+ *
+ * - The text before the cursor is the most important information to IMEs.
+ * - The text after the cursor is the second important information to IMEs.
+ * - The selected text is the least important information but it shall NEVER be truncated.
+ * When it is too long, just drop it.
+ *
+ *
+ * For example, the subText can be viewed as TextBeforeCursor + Selection + TextAfterCursor.
+ * The result could be:
+ *
+ * - (maybeTrimmedAtHead)TextBeforeCursor + Selection
+ * + TextAfterCursor(maybeTrimmedAtTail)
+ * - (maybeTrimmedAtHead)TextBeforeCursor + TextAfterCursor(maybeTrimmedAtTail)
+ *
+ *
+ * @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
- CREATOR = new Parcelable.Creator() {
- @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();
- }
- }
- }
- }
-}
+}
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/SurroundingText.java b/core/java/android/view/inputmethod/SurroundingText.java
index 94e05a830b850..c85a18a1df794 100644
--- a/core/java/android/view/inputmethod/SurroundingText.java
+++ b/core/java/android/view/inputmethod/SurroundingText.java
@@ -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();
+ }
+ }
+ }
}
diff --git a/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java
index 92fb52837c362..c636912ee98d0 100644
--- a/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/EditorInfoTest.java
@@ -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) {