From b416297433c91ff6694fdf5ce41f7ab6f1ee346b Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Fri, 5 May 2017 18:07:17 +0100 Subject: [PATCH] Reject smart selection if outside original selection. - The aim is to be defensive and prefer to reject a selection if it is likely to be wrong. Test: bit FrameworksCoreTests:android.view.textclassifier.TextClassificationManagerTest Bug: 38019270 Change-Id: I35ebc84fb102373949366296434a31d899edfef3 --- .../textclassifier/TextClassifierImpl.java | 4 +++- .../TextClassificationManagerTest.java | 23 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java index 209ff097f9e6c..dbe705ee90903 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -102,7 +102,9 @@ final class TextClassifierImpl implements TextClassifier { string, selectionStartIndex, selectionEndIndex); final int start = startEnd[0]; final int end = startEnd[1]; - if (start >= 0 && end <= string.length() && start <= end) { + if (start <= end + && start >= 0 && end <= string.length() + && start <= selectionStartIndex && end >= selectionEndIndex) { final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end); final SmartSelection.ClassificationResult[] results = smartSelection.classifyText( diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java index 742fd60e25f7a..7b7031bb35348 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java @@ -40,6 +40,7 @@ import java.util.Locale; public class TextClassificationManagerTest { private static final LocaleList LOCALES = LocaleList.forLanguageTags("en"); + private static final String NO_TYPE = null; private TextClassificationManager mTcm; private TextClassifier mClassifier; @@ -101,6 +102,19 @@ public class TextClassificationManagerTest { isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_URL)); } + @Test + public void testSmartSelection_withEmoji() { + if (isTextClassifierDisabled()) return; + + String text = "\uD83D\uDE02 Hello."; + String selected = "Hello"; + int startIndex = text.indexOf(selected); + int endIndex = startIndex + selected.length(); + + assertThat(mClassifier.suggestSelection(text, startIndex, endIndex, LOCALES), + isTextSelection(startIndex, endIndex, NO_TYPE)); + } + @Test public void testClassifyText() { if (isTextClassifierDisabled()) return; @@ -172,12 +186,17 @@ public class TextClassificationManagerTest { TextSelection selection = (TextSelection) o; return startIndex == selection.getSelectionStartIndex() && endIndex == selection.getSelectionEndIndex() - && selection.getEntityCount() > 0 - && type.equals(selection.getEntity(0)); + && typeMatches(selection, type); } return false; } + private boolean typeMatches(TextSelection selection, String type) { + return type == null + || (selection.getEntityCount() > 0 + && type.trim().equalsIgnoreCase(selection.getEntity(0))); + } + @Override public void describeTo(Description description) { description.appendValue(