Merge "Fix app crash if the selection is from reverse direction."

This commit is contained in:
Joanne Chung
2020-07-06 10:50:14 +00:00
committed by Gerrit Code Review

View File

@@ -104,17 +104,44 @@ public final class SelectionActionModeHelper {
} }
} }
/**
* Swap the selection index if the start index is greater than end index.
*
* @return the swap result, index 0 is the start index and index 1 is the end index.
*/
private static int[] sortSelctionIndices(int selectionStart, int selectionEnd) {
if (selectionStart < selectionEnd) {
return new int[]{selectionStart, selectionEnd};
}
return new int[]{selectionEnd, selectionStart};
}
/**
* The {@link TextView} selection start and end index may not be sorted, this method will swap
* the {@link TextView} selection index if the start index is greater than end index.
*
* @param textView the selected TextView.
* @return the swap result, index 0 is the start index and index 1 is the end index.
*/
private static int[] sortSelctionIndicesFromTextView(TextView textView) {
int selectionStart = textView.getSelectionStart();
int selectionEnd = textView.getSelectionEnd();
return sortSelctionIndices(selectionStart, selectionEnd);
}
/** /**
* Starts Selection ActionMode. * Starts Selection ActionMode.
*/ */
public void startSelectionActionModeAsync(boolean adjustSelection) { public void startSelectionActionModeAsync(boolean adjustSelection) {
// Check if the smart selection should run for editable text. // Check if the smart selection should run for editable text.
adjustSelection &= getTextClassificationSettings().isSmartSelectionEnabled(); adjustSelection &= getTextClassificationSettings().isSmartSelectionEnabled();
int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
mSelectionTracker.onOriginalSelection( mSelectionTracker.onOriginalSelection(
getText(mTextView), getText(mTextView),
mTextView.getSelectionStart(), sortedSelectionIndices[0],
mTextView.getSelectionEnd(), sortedSelectionIndices[1],
false /*isLink*/); false /*isLink*/);
cancelAsyncTask(); cancelAsyncTask();
if (skipTextClassification()) { if (skipTextClassification()) {
@@ -139,12 +166,14 @@ public final class SelectionActionModeHelper {
* Starts Link ActionMode. * Starts Link ActionMode.
*/ */
public void startLinkActionModeAsync(int start, int end) { public void startLinkActionModeAsync(int start, int end) {
mSelectionTracker.onOriginalSelection(getText(mTextView), start, end, true /*isLink*/); int[] indexResult = sortSelctionIndices(start, end);
mSelectionTracker.onOriginalSelection(getText(mTextView), indexResult[0], indexResult[1],
true /*isLink*/);
cancelAsyncTask(); cancelAsyncTask();
if (skipTextClassification()) { if (skipTextClassification()) {
startLinkActionMode(null); startLinkActionMode(null);
} else { } else {
resetTextClassificationHelper(start, end); resetTextClassificationHelper(indexResult[0], indexResult[1]);
mTextClassificationAsyncTask = new TextClassificationAsyncTask( mTextClassificationAsyncTask = new TextClassificationAsyncTask(
mTextView, mTextView,
mTextClassificationHelper.getTimeoutDuration(), mTextClassificationHelper.getTimeoutDuration(),
@@ -173,19 +202,23 @@ public final class SelectionActionModeHelper {
/** Reports a selection action event. */ /** Reports a selection action event. */
public void onSelectionAction(int menuItemId, @Nullable String actionLabel) { public void onSelectionAction(int menuItemId, @Nullable String actionLabel) {
int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
mSelectionTracker.onSelectionAction( mSelectionTracker.onSelectionAction(
mTextView.getSelectionStart(), mTextView.getSelectionEnd(), sortedSelectionIndices[0], sortedSelectionIndices[1],
getActionType(menuItemId), actionLabel, mTextClassification); getActionType(menuItemId), actionLabel, mTextClassification);
} }
public void onSelectionDrag() { public void onSelectionDrag() {
int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
mSelectionTracker.onSelectionAction( mSelectionTracker.onSelectionAction(
mTextView.getSelectionStart(), mTextView.getSelectionEnd(), sortedSelectionIndices[0], sortedSelectionIndices[1],
SelectionEvent.ACTION_DRAG, /* actionLabel= */ null, mTextClassification); SelectionEvent.ACTION_DRAG, /* actionLabel= */ null, mTextClassification);
} }
public void onTextChanged(int start, int end) { public void onTextChanged(int start, int end) {
mSelectionTracker.onTextChanged(start, end, mTextClassification); int[] sortedSelectionIndices = sortSelctionIndices(start, end);
mSelectionTracker.onTextChanged(sortedSelectionIndices[0], sortedSelectionIndices[1],
mTextClassification);
} }
public boolean resetSelection(int textIndex) { public boolean resetSelection(int textIndex) {
@@ -302,9 +335,10 @@ public final class SelectionActionModeHelper {
startSelectionActionMode(startSelectionResult); startSelectionActionMode(startSelectionResult);
}; };
// TODO do not trigger the animation if the change included only non-printable characters // TODO do not trigger the animation if the change included only non-printable characters
int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
final boolean didSelectionChange = final boolean didSelectionChange =
result != null && (mTextView.getSelectionStart() != result.mStart result != null && (sortedSelectionIndices[0] != result.mStart
|| mTextView.getSelectionEnd() != result.mEnd); || sortedSelectionIndices[1] != result.mEnd);
if (!didSelectionChange) { if (!didSelectionChange) {
onAnimationEndCallback.run(); onAnimationEndCallback.run();
@@ -454,16 +488,18 @@ public final class SelectionActionModeHelper {
if (actionMode != null) { if (actionMode != null) {
actionMode.invalidate(); actionMode.invalidate();
} }
final int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
mSelectionTracker.onSelectionUpdated( mSelectionTracker.onSelectionUpdated(
mTextView.getSelectionStart(), mTextView.getSelectionEnd(), mTextClassification); sortedSelectionIndices[0], sortedSelectionIndices[1], mTextClassification);
mTextClassificationAsyncTask = null; mTextClassificationAsyncTask = null;
} }
private void resetTextClassificationHelper(int selectionStart, int selectionEnd) { private void resetTextClassificationHelper(int selectionStart, int selectionEnd) {
if (selectionStart < 0 || selectionEnd < 0) { if (selectionStart < 0 || selectionEnd < 0) {
// Use selection indices // Use selection indices
selectionStart = mTextView.getSelectionStart(); int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
selectionEnd = mTextView.getSelectionEnd(); selectionStart = sortedSelectionIndices[0];
selectionEnd = sortedSelectionIndices[1];
} }
mTextClassificationHelper.init( mTextClassificationHelper.init(
mTextView::getTextClassifier, mTextView::getTextClassifier,
@@ -603,10 +639,11 @@ public final class SelectionActionModeHelper {
mAllowReset = false; mAllowReset = false;
boolean selected = editor.selectCurrentWord(); boolean selected = editor.selectCurrentWord();
if (selected) { if (selected) {
mSelectionStart = editor.getTextView().getSelectionStart(); final int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(textView);
mSelectionEnd = editor.getTextView().getSelectionEnd(); mSelectionStart = sortedSelectionIndices[0];
mSelectionEnd = sortedSelectionIndices[1];
mLogger.logSelectionAction( mLogger.logSelectionAction(
textView.getSelectionStart(), textView.getSelectionEnd(), sortedSelectionIndices[0], sortedSelectionIndices[1],
SelectionEvent.ACTION_RESET, SelectionEvent.ACTION_RESET,
/* actionLabel= */ null, /* classification= */ null); /* actionLabel= */ null, /* classification= */ null);
} }
@@ -1179,8 +1216,9 @@ public final class SelectionActionModeHelper {
SelectionResult(int start, int end, SelectionResult(int start, int end,
@Nullable TextClassification classification, @Nullable TextSelection selection) { @Nullable TextClassification classification, @Nullable TextSelection selection) {
mStart = start; int[] sortedIndices = sortSelctionIndices(start, end);
mEnd = end; mStart = sortedIndices[0];
mEnd = sortedIndices[1];
mClassification = classification; mClassification = classification;
mSelection = selection; mSelection = selection;
} }