Refine surrounding text logic and test case readability.
1. Follow up refinement for CL[1].
2. Test case to verify the InitialSurroundingText parcel
wrapping/unwrapping logic.
[1] c486acc4d2, Ie04f2349b1157408aa8ed9044aea12ce99132cb4
Bug: 148035211
Test: atest FrameworksCoreTests:EditorInfoTest
Change-Id: I9609b8a7dabb6285ed673cb0890bb3019e3b7caa
This commit is contained in:
@@ -33,11 +33,11 @@ import android.util.Printer;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An EditorInfo describes several attributes of a text editing object
|
||||
@@ -558,7 +558,7 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
* editor wants to trim out the first 10 chars, subTextStart should be 10.
|
||||
*/
|
||||
public void setInitialSurroundingSubText(@NonNull CharSequence subText, int subTextStart) {
|
||||
Preconditions.checkNotNull(subText);
|
||||
Objects.requireNonNull(subText);
|
||||
|
||||
// Swap selection start and end if necessary.
|
||||
final int subTextSelStart = initialSelStart > initialSelEnd
|
||||
@@ -585,25 +585,35 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
return;
|
||||
}
|
||||
|
||||
// The input text is too long. Let's try to trim it reasonably. Fundamental rules are:
|
||||
// 1. Text before the cursor is the most important information to IMEs.
|
||||
// 2. Text after the cursor is the second important information to IMEs.
|
||||
// 3. Selected text is the least important information but it shall NEVER be truncated.
|
||||
// When it is too long, just drop it.
|
||||
//
|
||||
// Source: <TextBeforeCursor><Selection><TextAfterCursor>
|
||||
// Possible results:
|
||||
// 1. <(maybeTrimmedAtHead)TextBeforeCursor><Selection><TextAfterCursor(maybeTrimmedAtTail)>
|
||||
// 2. <(maybeTrimmedAtHead)TextBeforeCursor><TextAfterCursor(maybeTrimmedAtTail)>
|
||||
//
|
||||
final int sourceSelLength = subTextSelEnd - subTextSelStart;
|
||||
trimLongSurroundingText(subText, subTextSelStart, subTextSelEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the initial surrounding text when it is over sized. 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.
|
||||
*<p><pre>
|
||||
* For example, the subText can be viewed as
|
||||
* TextBeforeCursor + Selection + TextAfterCursor
|
||||
* The result could be
|
||||
* 1. (maybeTrimmedAtHead)TextBeforeCursor + Selection + TextAfterCursor(maybeTrimmedAtTail)
|
||||
* 2. (maybeTrimmedAtHead)TextBeforeCursor + TextAfterCursor(maybeTrimmedAtTail)</pre>
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
private void trimLongSurroundingText(CharSequence subText, int selStart, int selEnd) {
|
||||
final int sourceSelLength = selEnd - selStart;
|
||||
// When the selected text is too long, drop it.
|
||||
final int newSelLength = (sourceSelLength > MAX_INITIAL_SELECTION_LENGTH)
|
||||
? 0 : sourceSelLength;
|
||||
|
||||
// Distribute rest of length quota to TextBeforeCursor and TextAfterCursor in 4:1 ratio.
|
||||
final int subTextBeforeCursorLength = subTextSelStart;
|
||||
final int subTextAfterCursorLength = subTextLength - subTextSelEnd;
|
||||
final int subTextBeforeCursorLength = selStart;
|
||||
final int subTextAfterCursorLength = subText.length() - selEnd;
|
||||
final int maxLengthMinusSelection = MEMORY_EFFICIENT_TEXT_LENGTH - newSelLength;
|
||||
final int possibleMaxBeforeCursorLength =
|
||||
Math.min(subTextBeforeCursorLength, (int) (0.8 * maxLengthMinusSelection));
|
||||
@@ -617,24 +627,23 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
|
||||
// We don't want to cut surrogate pairs in the middle. Exam that at the new head and tail.
|
||||
if (isCutOnSurrogate(subText,
|
||||
subTextSelStart - newBeforeCursorLength, TrimPolicy.HEAD)) {
|
||||
selStart - newBeforeCursorLength, TrimPolicy.HEAD)) {
|
||||
newBeforeCursorHead = newBeforeCursorHead + 1;
|
||||
newBeforeCursorLength = newBeforeCursorLength - 1;
|
||||
}
|
||||
if (isCutOnSurrogate(subText,
|
||||
subTextSelEnd + newAfterCursorLength - 1, TrimPolicy.TAIL)) {
|
||||
selEnd + newAfterCursorLength - 1, TrimPolicy.TAIL)) {
|
||||
newAfterCursorLength = newAfterCursorLength - 1;
|
||||
}
|
||||
|
||||
// Now we know where to trim, compose the initialSurroundingText.
|
||||
final int newTextLength = newBeforeCursorLength + newSelLength + newAfterCursorLength;
|
||||
CharSequence newInitialSurroundingText;
|
||||
final CharSequence newInitialSurroundingText;
|
||||
if (newSelLength != sourceSelLength) {
|
||||
final CharSequence beforeCursor = subText.subSequence(newBeforeCursorHead,
|
||||
newBeforeCursorHead + newBeforeCursorLength);
|
||||
|
||||
final CharSequence afterCursor = subText.subSequence(subTextSelEnd,
|
||||
subTextSelEnd + newAfterCursorLength);
|
||||
final CharSequence afterCursor = subText.subSequence(selEnd,
|
||||
selEnd + newAfterCursorLength);
|
||||
|
||||
newInitialSurroundingText = TextUtils.concat(beforeCursor, afterCursor);
|
||||
} else {
|
||||
@@ -651,15 +660,16 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get <var>n</var> characters of text before the current cursor position. May be {@code null}
|
||||
* when the protocol is not supported.
|
||||
* Get <var>length</var> characters of text before the current cursor position. May be
|
||||
* {@code null} when the protocol is not supported.
|
||||
*
|
||||
* @param length The expected length of the text.
|
||||
* @param flags Supplies additional options controlling how the text is returned. May be
|
||||
* either 0 or {@link InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
* @return the text before the cursor position; the length of the returned text might be less
|
||||
* than <var>n</var>. When there is no text before the cursor, an empty string will be returned.
|
||||
* It could also be {@code null} when the editor or system could not support this protocol.
|
||||
* than <var>length</var>. When there is no text before the cursor, an empty string will be
|
||||
* returned. It could also be {@code null} when the editor or system could not support this
|
||||
* protocol.
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getInitialTextBeforeCursor(int length, int flags) {
|
||||
@@ -667,8 +677,8 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selected text, if any. May be {@code null} when no text is selected or the selected
|
||||
* text is way too long.
|
||||
* Gets the selected text, if any. May be {@code null} when the protocol is not supported or the
|
||||
* selected text is way too long.
|
||||
*
|
||||
* @param flags Supplies additional options controlling how the text is returned. May be
|
||||
* either 0 or {@link InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
@@ -693,15 +703,16 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get <var>n</var> characters of text after the current cursor position. May be {@code null}
|
||||
* when the protocol is not supported.
|
||||
* Get <var>length</var> characters of text after the current cursor position. May be
|
||||
* {@code null} when the protocol is not supported.
|
||||
*
|
||||
* @param length The expected length of the text.
|
||||
* @param flags Supplies additional options controlling how the text is returned. May be
|
||||
* either 0 or {@link InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
* @return the text after the cursor position; the length of the returned text might be less
|
||||
* than <var>n</var>. When there is no text after the cursor, an empty string will be returned.
|
||||
* It could also be {@code null} when the editor or system could not support this protocol.
|
||||
* than <var>length</var>. When there is no text after the cursor, an empty string will be
|
||||
* returned. It could also be {@code null} when the editor or system could not support this
|
||||
* protocol.
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getInitialTextAfterCursor(int length, int flags) {
|
||||
@@ -863,7 +874,6 @@ public class EditorInfo implements InputType, Parcelable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(b/148035211): Unit tests for this class
|
||||
static final class InitialSurroundingText implements Parcelable {
|
||||
@Nullable final CharSequence mSurroundingText;
|
||||
final int mSelectionHead;
|
||||
|
||||
@@ -20,11 +20,11 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.UserHandle;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.junit.runner.RunWith;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class EditorInfoTest {
|
||||
private static final int TEST_USER_ID = 42;
|
||||
private static final int LONG_EXP_TEXT_LENGTH = EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH * 2;
|
||||
|
||||
/**
|
||||
* Makes sure that {@code null} {@link EditorInfo#targetInputMethodUser} can be copied via
|
||||
@@ -79,8 +80,8 @@ public class EditorInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullTextInputComposeInitialSurroundingText() {
|
||||
final Spannable testText = null;
|
||||
public void setInitialText_nullInputText_throwsException() {
|
||||
final CharSequence testText = null;
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
|
||||
try {
|
||||
@@ -92,56 +93,75 @@ public class EditorInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonNullTextInputComposeInitialSurroundingText() {
|
||||
final Spannable testText = createTestText(/* prependLength= */ 0,
|
||||
EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
public void setInitialText_cursorAtHead_dividesByCursorPosition() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
|
||||
// Cursor at position 0.
|
||||
int selectionLength = 0;
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
final int selectionLength = 0;
|
||||
editorInfo.initialSelStart = 0;
|
||||
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
|
||||
int expectedTextBeforeCursorLength = 0;
|
||||
int expectedTextAfterCursorLength = testText.length();
|
||||
final int expectedTextBeforeCursorLength = 0;
|
||||
final int expectedTextAfterCursorLength = testText.length();
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
}
|
||||
|
||||
// Cursor at the end.
|
||||
@Test
|
||||
public void setInitialText_cursorAtTail_dividesByCursorPosition() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
final int selectionLength = 0;
|
||||
editorInfo.initialSelStart = testText.length() - selectionLength;
|
||||
editorInfo.initialSelEnd = testText.length();
|
||||
expectedTextBeforeCursorLength = testText.length();
|
||||
expectedTextAfterCursorLength = 0;
|
||||
final int expectedTextBeforeCursorLength = testText.length();
|
||||
final int expectedTextAfterCursorLength = 0;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
}
|
||||
|
||||
// Cursor at the middle.
|
||||
selectionLength = 2;
|
||||
@Test
|
||||
public void setInitialText_cursorAtMiddle_dividesByCursorPosition() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
final int selectionLength = 2;
|
||||
editorInfo.initialSelStart = testText.length() / 2;
|
||||
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
|
||||
expectedTextBeforeCursorLength = editorInfo.initialSelStart;
|
||||
expectedTextAfterCursorLength = testText.length() - editorInfo.initialSelEnd;
|
||||
final int expectedTextBeforeCursorLength = editorInfo.initialSelStart;
|
||||
final int expectedTextAfterCursorLength = testText.length() - editorInfo.initialSelEnd;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
}
|
||||
|
||||
// Accidentally swap selection start and end.
|
||||
@Test
|
||||
public void setInitialText_incorrectCursorOrder_correctsThenDivide() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
final int selectionLength = 2;
|
||||
editorInfo.initialSelEnd = testText.length() / 2;
|
||||
editorInfo.initialSelStart = editorInfo.initialSelEnd + selectionLength;
|
||||
final int expectedTextBeforeCursorLength = testText.length() / 2;
|
||||
final int expectedTextAfterCursorLength = testText.length() - testText.length() / 2
|
||||
- selectionLength;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
}
|
||||
|
||||
// Invalid cursor position.
|
||||
@Test
|
||||
public void setInitialText_invalidCursorPosition_returnsNull() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
editorInfo.initialSelStart = -1;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
@@ -153,64 +173,33 @@ public class EditorInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTooLongTextInputComposeInitialSurroundingText() {
|
||||
final Spannable testText = createTestText(/* prependLength= */ 0,
|
||||
EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH + 2);
|
||||
public void setOverSizeInitialText_cursorAtMiddle_dividesProportionately() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH + 2);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
|
||||
// Cursor at position 0.
|
||||
int selectionLength = 0;
|
||||
editorInfo.initialSelStart = 0;
|
||||
editorInfo.initialSelEnd = 0 + selectionLength;
|
||||
int expectedTextBeforeCursorLength = 0;
|
||||
int expectedTextAfterCursorLength = editorInfo.MEMORY_EFFICIENT_TEXT_LENGTH;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
|
||||
// Cursor at the end.
|
||||
editorInfo.initialSelStart = testText.length() - selectionLength;
|
||||
editorInfo.initialSelEnd = testText.length();
|
||||
expectedTextBeforeCursorLength = editorInfo.MEMORY_EFFICIENT_TEXT_LENGTH;
|
||||
expectedTextAfterCursorLength = 0;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
|
||||
// Cursor at the middle.
|
||||
selectionLength = 2;
|
||||
final int selectionLength = 2;
|
||||
editorInfo.initialSelStart = testText.length() / 2;
|
||||
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
|
||||
expectedTextBeforeCursorLength = Math.min(editorInfo.initialSelStart,
|
||||
final int expectedTextBeforeCursorLength = Math.min(editorInfo.initialSelStart,
|
||||
(int) (0.8 * (EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH - selectionLength)));
|
||||
expectedTextAfterCursorLength = EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH
|
||||
final int expectedTextAfterCursorLength = EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH
|
||||
- expectedTextBeforeCursorLength - selectionLength;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
}
|
||||
|
||||
// Accidentally swap selection start and end.
|
||||
editorInfo.initialSelEnd = testText.length() / 2;
|
||||
editorInfo.initialSelStart = editorInfo.initialSelEnd + selectionLength;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
assertExpectedTextLength(editorInfo, expectedTextBeforeCursorLength, selectionLength,
|
||||
expectedTextAfterCursorLength);
|
||||
|
||||
// Selection too long, selected text should be dropped.
|
||||
selectionLength = EditorInfo.MAX_INITIAL_SELECTION_LENGTH + 1;
|
||||
@Test
|
||||
public void setOverSizeInitialText_overSizeSelection_dropsSelection() {
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH + 2);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
final int selectionLength = EditorInfo.MAX_INITIAL_SELECTION_LENGTH + 1;
|
||||
editorInfo.initialSelStart = testText.length() / 2;
|
||||
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
|
||||
expectedTextBeforeCursorLength = Math.min(editorInfo.initialSelStart,
|
||||
final int expectedTextBeforeCursorLength = Math.min(editorInfo.initialSelStart,
|
||||
(int) (0.8 * EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH));
|
||||
expectedTextAfterCursorLength = testText.length() - editorInfo.initialSelEnd;
|
||||
final int expectedTextAfterCursorLength = testText.length() - editorInfo.initialSelEnd;
|
||||
|
||||
editorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
@@ -219,34 +208,59 @@ public class EditorInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTooLongSubTextInputComposeInitialSurroundingText() {
|
||||
final int prependLength = 5;
|
||||
final int subTextLength = EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH;
|
||||
final Spannable fullText = createTestText(prependLength, subTextLength);
|
||||
public void setInitialSubText_trimmedSubText_dividesByOriginalCursorPosition() {
|
||||
final String prefixString = "prefix";
|
||||
final CharSequence subText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final CharSequence originalText = TextUtils.concat(prefixString, subText);
|
||||
final EditorInfo editorInfo = new EditorInfo();
|
||||
// Cursor at the middle.
|
||||
final int selectionLength = 2;
|
||||
editorInfo.initialSelStart = fullText.length() / 2;
|
||||
editorInfo.initialSelEnd = editorInfo.initialSelStart + selectionLength;
|
||||
// #prependLength characters will be trimmed out.
|
||||
final Spannable expectedTextBeforeCursor = createExpectedText(/* startNumber= */0,
|
||||
editorInfo.initialSelStart - prependLength);
|
||||
final Spannable expectedSelectedText = createExpectedText(
|
||||
editorInfo.initialSelStart - prependLength, selectionLength);
|
||||
final Spannable expectedTextAfterCursor = createExpectedText(
|
||||
editorInfo.initialSelEnd - prependLength,
|
||||
fullText.length() - editorInfo.initialSelEnd);
|
||||
final int selLength = 2;
|
||||
editorInfo.initialSelStart = originalText.length() / 2;
|
||||
editorInfo.initialSelEnd = editorInfo.initialSelStart + selLength;
|
||||
final CharSequence expectedTextBeforeCursor = createExpectedText(/* startNumber= */0,
|
||||
editorInfo.initialSelStart - prefixString.length());
|
||||
final CharSequence expectedSelectedText = createExpectedText(
|
||||
editorInfo.initialSelStart - prefixString.length(), selLength);
|
||||
final CharSequence expectedTextAfterCursor = createExpectedText(
|
||||
editorInfo.initialSelEnd - prefixString.length(),
|
||||
originalText.length() - editorInfo.initialSelEnd);
|
||||
|
||||
editorInfo.setInitialSurroundingSubText(fullText.subSequence(prependLength,
|
||||
fullText.length()), prependLength);
|
||||
editorInfo.setInitialSurroundingSubText(subText, prefixString.length());
|
||||
|
||||
assertTrue(TextUtils.equals(expectedTextBeforeCursor,
|
||||
editorInfo.getInitialTextBeforeCursor(editorInfo.MEMORY_EFFICIENT_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES)));
|
||||
editorInfo.getInitialTextBeforeCursor(LONG_EXP_TEXT_LENGTH, anyInt())));
|
||||
assertTrue(TextUtils.equals(expectedSelectedText,
|
||||
editorInfo.getInitialSelectedText(InputConnection.GET_TEXT_WITH_STYLES)));
|
||||
editorInfo.getInitialSelectedText(anyInt())));
|
||||
assertTrue(TextUtils.equals(expectedTextAfterCursor,
|
||||
editorInfo.getInitialTextAfterCursor(editorInfo.MEMORY_EFFICIENT_TEXT_LENGTH,
|
||||
editorInfo.getInitialTextAfterCursor(LONG_EXP_TEXT_LENGTH, anyInt())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialSurroundingText_wrapIntoParcel_staysIntact() {
|
||||
// EditorInfo.InitialSurroundingText is not visible to test class. But all its key elements
|
||||
// must stay intact for its getter methods to return correct value and it will be wrapped
|
||||
// into its outer class for parcel transfer, therefore we can verify its parcel
|
||||
// wrapping/unwrapping logic through its outer class.
|
||||
final CharSequence testText = createTestText(EditorInfo.MEMORY_EFFICIENT_TEXT_LENGTH);
|
||||
final EditorInfo sourceEditorInfo = new EditorInfo();
|
||||
final int selectionLength = 2;
|
||||
sourceEditorInfo.initialSelStart = testText.length() / 2;
|
||||
sourceEditorInfo.initialSelEnd = sourceEditorInfo.initialSelStart + selectionLength;
|
||||
sourceEditorInfo.setInitialSurroundingText(testText);
|
||||
|
||||
final EditorInfo targetEditorInfo = cloneViaParcel(sourceEditorInfo);
|
||||
|
||||
assertTrue(TextUtils.equals(
|
||||
sourceEditorInfo.getInitialTextBeforeCursor(LONG_EXP_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES),
|
||||
targetEditorInfo.getInitialTextBeforeCursor(LONG_EXP_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES)));
|
||||
assertTrue(TextUtils.equals(
|
||||
sourceEditorInfo.getInitialSelectedText(InputConnection.GET_TEXT_WITH_STYLES),
|
||||
targetEditorInfo.getInitialSelectedText(InputConnection.GET_TEXT_WITH_STYLES)));
|
||||
assertTrue(TextUtils.equals(
|
||||
sourceEditorInfo.getInitialTextAfterCursor(LONG_EXP_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES),
|
||||
targetEditorInfo.getInitialTextAfterCursor(LONG_EXP_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES)));
|
||||
}
|
||||
|
||||
@@ -254,12 +268,12 @@ public class EditorInfoTest {
|
||||
@Nullable Integer expectBeforeCursorLength, @Nullable Integer expectSelectionLength,
|
||||
@Nullable Integer expectAfterCursorLength) {
|
||||
final CharSequence textBeforeCursor =
|
||||
editorInfo.getInitialTextBeforeCursor(editorInfo.MEMORY_EFFICIENT_TEXT_LENGTH,
|
||||
editorInfo.getInitialTextBeforeCursor(LONG_EXP_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES);
|
||||
final CharSequence selectedText =
|
||||
editorInfo.getInitialSelectedText(InputConnection.GET_TEXT_WITH_STYLES);
|
||||
final CharSequence textAfterCursor =
|
||||
editorInfo.getInitialTextAfterCursor(editorInfo.MEMORY_EFFICIENT_TEXT_LENGTH,
|
||||
editorInfo.getInitialTextAfterCursor(LONG_EXP_TEXT_LENGTH,
|
||||
InputConnection.GET_TEXT_WITH_STYLES);
|
||||
|
||||
if (expectBeforeCursorLength == null) {
|
||||
@@ -281,19 +295,15 @@ public class EditorInfoTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static Spannable createTestText(int prependLength, int surroundingLength) {
|
||||
private static CharSequence createTestText(int surroundingLength) {
|
||||
final SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
for (int i = 0; i < prependLength; i++) {
|
||||
builder.append("a");
|
||||
}
|
||||
|
||||
for (int i = 0; i < surroundingLength; i++) {
|
||||
builder.append(Integer.toString(i % 10));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static Spannable createExpectedText(int startNumber, int length) {
|
||||
private static CharSequence createExpectedText(int startNumber, int length) {
|
||||
final SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
for (int i = startNumber; i < startNumber + length; i++) {
|
||||
builder.append(Integer.toString(i % 10));
|
||||
|
||||
Reference in New Issue
Block a user