Loading core/java/android/widget/Editor.java +2 −1 Original line number Diff line number Diff line Loading @@ -1262,7 +1262,8 @@ public class Editor { } } void sendOnTextChanged(int start, int after) { void sendOnTextChanged(int start, int before, int after) { getSelectionActionModeHelper().onTextChanged(start, start + before); updateSpellCheckSpans(start, start + after, false); // Flip flag to indicate the word iterator needs to have the text reset. Loading core/java/android/widget/SelectionActionModeHelper.java +29 −16 Original line number Diff line number Diff line Loading @@ -146,10 +146,8 @@ public final class SelectionActionModeHelper { SelectionEvent.ActionType.DRAG, mTextClassification); } public void onTypeOverSelection() { mSelectionTracker.onSelectionAction( mTextView.getSelectionStart(), mTextView.getSelectionEnd(), SelectionEvent.ActionType.OVERTYPE, mTextClassification); public void onTextChanged(int start, int end) { mSelectionTracker.onTextChanged(start, end, mTextClassification); } public boolean resetSelection(int textIndex) { Loading Loading @@ -383,7 +381,6 @@ public final class SelectionActionModeHelper { private int mOriginalEnd; private int mSelectionStart; private int mSelectionEnd; private boolean mSelectionStarted; private boolean mAllowReset; SelectionTracker(TextView textView) { Loading @@ -396,9 +393,8 @@ public final class SelectionActionModeHelper { */ public void onOriginalSelection( CharSequence text, int selectionStart, int selectionEnd, boolean editableText) { mOriginalStart = selectionStart; mOriginalEnd = selectionEnd; mSelectionStarted = true; mOriginalStart = mSelectionStart = selectionStart; mOriginalEnd = mSelectionEnd = selectionEnd; mAllowReset = false; maybeInvalidateLogger(); mLogger.logSelectionStarted(text, selectionStart); Loading @@ -408,7 +404,7 @@ public final class SelectionActionModeHelper { * Called when selection action mode is started and the results come from a classifier. */ public void onSmartSelection(SelectionResult result) { if (mSelectionStarted) { if (isSelectionStarted()) { mSelectionStart = result.mStart; mSelectionEnd = result.mEnd; mAllowReset = mSelectionStart != mOriginalStart || mSelectionEnd != mOriginalEnd; Loading @@ -423,7 +419,9 @@ public final class SelectionActionModeHelper { public void onSelectionUpdated( int selectionStart, int selectionEnd, @Nullable TextClassification classification) { if (mSelectionStarted) { if (isSelectionStarted()) { mSelectionStart = selectionStart; mSelectionEnd = selectionEnd; mAllowReset = false; mLogger.logSelectionModified(selectionStart, selectionEnd, classification, null); } Loading @@ -434,10 +432,13 @@ public final class SelectionActionModeHelper { */ public void onSelectionDestroyed() { mAllowReset = false; mSelectionStarted = false; // Wait a few ms to see if the selection was destroyed because of a text change event. mTextView.postDelayed(() -> { mLogger.logSelectionAction( mSelectionStart, mSelectionEnd, SelectionEvent.ActionType.ABANDON, null /* classification */); mSelectionStart = mSelectionEnd = -1; }, 100 /* ms */); } /** Loading @@ -447,7 +448,7 @@ public final class SelectionActionModeHelper { int selectionStart, int selectionEnd, @SelectionEvent.ActionType int action, @Nullable TextClassification classification) { if (mSelectionStarted) { if (isSelectionStarted()) { mAllowReset = false; mLogger.logSelectionAction(selectionStart, selectionEnd, action, classification); } Loading @@ -461,13 +462,15 @@ public final class SelectionActionModeHelper { */ public boolean resetSelection(int textIndex, Editor editor) { final TextView textView = editor.getTextView(); if (mSelectionStarted if (isSelectionStarted() && mAllowReset && textIndex >= mSelectionStart && textIndex <= mSelectionEnd && textView.getText() instanceof Spannable) { mAllowReset = false; boolean selected = editor.selectCurrentWord(); if (selected) { mSelectionStart = editor.getTextView().getSelectionStart(); mSelectionEnd = editor.getTextView().getSelectionEnd(); mLogger.logSelectionAction( textView.getSelectionStart(), textView.getSelectionEnd(), SelectionEvent.ActionType.RESET, null /* classification */); Loading @@ -477,11 +480,21 @@ public final class SelectionActionModeHelper { return false; } public void onTextChanged(int start, int end, TextClassification classification) { if (isSelectionStarted() && start == mSelectionStart && end == mSelectionEnd) { onSelectionAction(start, end, SelectionEvent.ActionType.OVERTYPE, classification); } } private void maybeInvalidateLogger() { if (mLogger.isEditTextLogger() != mTextView.isTextEditable()) { mLogger = new SelectionMetricsLogger(mTextView); } } private boolean isSelectionStarted() { return mSelectionStart >= 0 && mSelectionEnd >= 0 && mSelectionStart != mSelectionEnd; } } // TODO: Write tests Loading core/java/android/widget/TextView.java +1 −1 Original line number Diff line number Diff line Loading @@ -9402,7 +9402,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } if (mEditor != null) mEditor.sendOnTextChanged(start, after); if (mEditor != null) mEditor.sendOnTextChanged(start, before, after); } /** Loading Loading
core/java/android/widget/Editor.java +2 −1 Original line number Diff line number Diff line Loading @@ -1262,7 +1262,8 @@ public class Editor { } } void sendOnTextChanged(int start, int after) { void sendOnTextChanged(int start, int before, int after) { getSelectionActionModeHelper().onTextChanged(start, start + before); updateSpellCheckSpans(start, start + after, false); // Flip flag to indicate the word iterator needs to have the text reset. Loading
core/java/android/widget/SelectionActionModeHelper.java +29 −16 Original line number Diff line number Diff line Loading @@ -146,10 +146,8 @@ public final class SelectionActionModeHelper { SelectionEvent.ActionType.DRAG, mTextClassification); } public void onTypeOverSelection() { mSelectionTracker.onSelectionAction( mTextView.getSelectionStart(), mTextView.getSelectionEnd(), SelectionEvent.ActionType.OVERTYPE, mTextClassification); public void onTextChanged(int start, int end) { mSelectionTracker.onTextChanged(start, end, mTextClassification); } public boolean resetSelection(int textIndex) { Loading Loading @@ -383,7 +381,6 @@ public final class SelectionActionModeHelper { private int mOriginalEnd; private int mSelectionStart; private int mSelectionEnd; private boolean mSelectionStarted; private boolean mAllowReset; SelectionTracker(TextView textView) { Loading @@ -396,9 +393,8 @@ public final class SelectionActionModeHelper { */ public void onOriginalSelection( CharSequence text, int selectionStart, int selectionEnd, boolean editableText) { mOriginalStart = selectionStart; mOriginalEnd = selectionEnd; mSelectionStarted = true; mOriginalStart = mSelectionStart = selectionStart; mOriginalEnd = mSelectionEnd = selectionEnd; mAllowReset = false; maybeInvalidateLogger(); mLogger.logSelectionStarted(text, selectionStart); Loading @@ -408,7 +404,7 @@ public final class SelectionActionModeHelper { * Called when selection action mode is started and the results come from a classifier. */ public void onSmartSelection(SelectionResult result) { if (mSelectionStarted) { if (isSelectionStarted()) { mSelectionStart = result.mStart; mSelectionEnd = result.mEnd; mAllowReset = mSelectionStart != mOriginalStart || mSelectionEnd != mOriginalEnd; Loading @@ -423,7 +419,9 @@ public final class SelectionActionModeHelper { public void onSelectionUpdated( int selectionStart, int selectionEnd, @Nullable TextClassification classification) { if (mSelectionStarted) { if (isSelectionStarted()) { mSelectionStart = selectionStart; mSelectionEnd = selectionEnd; mAllowReset = false; mLogger.logSelectionModified(selectionStart, selectionEnd, classification, null); } Loading @@ -434,10 +432,13 @@ public final class SelectionActionModeHelper { */ public void onSelectionDestroyed() { mAllowReset = false; mSelectionStarted = false; // Wait a few ms to see if the selection was destroyed because of a text change event. mTextView.postDelayed(() -> { mLogger.logSelectionAction( mSelectionStart, mSelectionEnd, SelectionEvent.ActionType.ABANDON, null /* classification */); mSelectionStart = mSelectionEnd = -1; }, 100 /* ms */); } /** Loading @@ -447,7 +448,7 @@ public final class SelectionActionModeHelper { int selectionStart, int selectionEnd, @SelectionEvent.ActionType int action, @Nullable TextClassification classification) { if (mSelectionStarted) { if (isSelectionStarted()) { mAllowReset = false; mLogger.logSelectionAction(selectionStart, selectionEnd, action, classification); } Loading @@ -461,13 +462,15 @@ public final class SelectionActionModeHelper { */ public boolean resetSelection(int textIndex, Editor editor) { final TextView textView = editor.getTextView(); if (mSelectionStarted if (isSelectionStarted() && mAllowReset && textIndex >= mSelectionStart && textIndex <= mSelectionEnd && textView.getText() instanceof Spannable) { mAllowReset = false; boolean selected = editor.selectCurrentWord(); if (selected) { mSelectionStart = editor.getTextView().getSelectionStart(); mSelectionEnd = editor.getTextView().getSelectionEnd(); mLogger.logSelectionAction( textView.getSelectionStart(), textView.getSelectionEnd(), SelectionEvent.ActionType.RESET, null /* classification */); Loading @@ -477,11 +480,21 @@ public final class SelectionActionModeHelper { return false; } public void onTextChanged(int start, int end, TextClassification classification) { if (isSelectionStarted() && start == mSelectionStart && end == mSelectionEnd) { onSelectionAction(start, end, SelectionEvent.ActionType.OVERTYPE, classification); } } private void maybeInvalidateLogger() { if (mLogger.isEditTextLogger() != mTextView.isTextEditable()) { mLogger = new SelectionMetricsLogger(mTextView); } } private boolean isSelectionStarted() { return mSelectionStart >= 0 && mSelectionEnd >= 0 && mSelectionStart != mSelectionEnd; } } // TODO: Write tests Loading
core/java/android/widget/TextView.java +1 −1 Original line number Diff line number Diff line Loading @@ -9402,7 +9402,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } if (mEditor != null) mEditor.sendOnTextChanged(start, after); if (mEditor != null) mEditor.sendOnTextChanged(start, before, after); } /** Loading