Loading core/java/android/text/util/Linkify.java +37 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.text.method.MovementMethod; import android.text.style.URLSpan; import android.util.Log; import android.util.Patterns; import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; Loading Loading @@ -78,6 +79,9 @@ import java.util.regex.Pattern; */ public class Linkify { private static final String LOG_TAG = "Linkify"; /** * Bit field indicating that web URLs should be matched in methods that * take an options mask Loading Loading @@ -247,6 +251,11 @@ public class Linkify { private static boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask, @Nullable Context context) { if (text != null && containsUnsupportedCharacters(text.toString())) { android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return false; } if (mask == 0) { return false; } Loading Loading @@ -292,6 +301,29 @@ public class Linkify { return true; } /** * Returns true if the specified text contains at least one unsupported character for applying * links. Also logs the error. * * @param text the text to apply links to * @hide */ public static boolean containsUnsupportedCharacters(String text) { if (text.contains("\u202C")) { Log.e(LOG_TAG, "Unsupported character for applying links: u202C"); return true; } if (text.contains("\u202D")) { Log.e(LOG_TAG, "Unsupported character for applying links: u202D"); return true; } if (text.contains("\u202E")) { Log.e(LOG_TAG, "Unsupported character for applying links: u202E"); return true; } return false; } /** * Scans the text of the provided TextView and turns all occurrences of * the link types indicated in the mask into clickable links. If matches Loading Loading @@ -462,6 +494,11 @@ public class Linkify { public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, @Nullable String defaultScheme, @Nullable String[] schemes, @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { if (spannable != null && containsUnsupportedCharacters(spannable.toString())) { android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return false; } final String[] schemesCopy; if (defaultScheme == null) defaultScheme = ""; if (schemes == null || schemes.length < 1) { Loading core/java/android/view/textclassifier/TextClassification.java +1 −1 Original line number Diff line number Diff line Loading @@ -104,7 +104,7 @@ public final class TextClassification implements Parcelable { /** * @hide */ static final TextClassification EMPTY = new TextClassification.Builder().build(); public static final TextClassification EMPTY = new TextClassification.Builder().build(); private static final String LOG_TAG = "TextClassification"; // TODO(toki): investigate a way to derive this based on device properties. Loading core/java/android/view/textclassifier/TextLinksParams.java +7 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,13 @@ public final class TextLinksParams { Preconditions.checkNotNull(textLinks); final String textString = text.toString(); if (Linkify.containsUnsupportedCharacters(textString)) { // Do not apply links to text containing unsupported characters. android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return TextLinks.STATUS_NO_LINKS_APPLIED; } if (!textString.startsWith(textLinks.getText())) { return TextLinks.STATUS_DIFFERENT_TEXT; } Loading core/java/android/widget/SelectionActionModeHelper.java +7 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.TextUtils; import android.text.util.Linkify; import android.util.Log; import android.view.ActionMode; import android.view.textclassifier.SelectionEvent; Loading Loading @@ -1045,7 +1046,12 @@ public final class SelectionActionModeHelper { trimText(); final TextClassification classification; if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { if (Linkify.containsUnsupportedCharacters(mText)) { // Do not show smart actions for text containing unsupported characters. android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); classification = TextClassification.EMPTY; } else if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { final TextClassification.Request request = new TextClassification.Request.Builder( mTrimmedText, mRelativeStart, mRelativeEnd) Loading core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ import android.service.textclassifier.TextClassifierService; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.Spannable; import android.text.SpannableString; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; Loading Loading @@ -306,6 +308,16 @@ public class TextClassificationManagerTest { mClassifier.generateLinks(request); } @Test public void testApplyLinks_unsupportedCharacter() { if (isTextClassifierDisabled()) return; Spannable url = new SpannableString("\u202Emoc.diordna.com"); TextLinks.Request request = new TextLinks.Request.Builder(url).build(); assertEquals( TextLinks.STATUS_NO_LINKS_APPLIED, mClassifier.generateLinks(request).apply(url, 0, null)); } @Test public void testSetTextClassifier() { TextClassifier classifier = mock(TextClassifier.class); Loading Loading
core/java/android/text/util/Linkify.java +37 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.text.method.MovementMethod; import android.text.style.URLSpan; import android.util.Log; import android.util.Patterns; import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; Loading Loading @@ -78,6 +79,9 @@ import java.util.regex.Pattern; */ public class Linkify { private static final String LOG_TAG = "Linkify"; /** * Bit field indicating that web URLs should be matched in methods that * take an options mask Loading Loading @@ -247,6 +251,11 @@ public class Linkify { private static boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask, @Nullable Context context) { if (text != null && containsUnsupportedCharacters(text.toString())) { android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return false; } if (mask == 0) { return false; } Loading Loading @@ -292,6 +301,29 @@ public class Linkify { return true; } /** * Returns true if the specified text contains at least one unsupported character for applying * links. Also logs the error. * * @param text the text to apply links to * @hide */ public static boolean containsUnsupportedCharacters(String text) { if (text.contains("\u202C")) { Log.e(LOG_TAG, "Unsupported character for applying links: u202C"); return true; } if (text.contains("\u202D")) { Log.e(LOG_TAG, "Unsupported character for applying links: u202D"); return true; } if (text.contains("\u202E")) { Log.e(LOG_TAG, "Unsupported character for applying links: u202E"); return true; } return false; } /** * Scans the text of the provided TextView and turns all occurrences of * the link types indicated in the mask into clickable links. If matches Loading Loading @@ -462,6 +494,11 @@ public class Linkify { public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, @Nullable String defaultScheme, @Nullable String[] schemes, @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { if (spannable != null && containsUnsupportedCharacters(spannable.toString())) { android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return false; } final String[] schemesCopy; if (defaultScheme == null) defaultScheme = ""; if (schemes == null || schemes.length < 1) { Loading
core/java/android/view/textclassifier/TextClassification.java +1 −1 Original line number Diff line number Diff line Loading @@ -104,7 +104,7 @@ public final class TextClassification implements Parcelable { /** * @hide */ static final TextClassification EMPTY = new TextClassification.Builder().build(); public static final TextClassification EMPTY = new TextClassification.Builder().build(); private static final String LOG_TAG = "TextClassification"; // TODO(toki): investigate a way to derive this based on device properties. Loading
core/java/android/view/textclassifier/TextLinksParams.java +7 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,13 @@ public final class TextLinksParams { Preconditions.checkNotNull(textLinks); final String textString = text.toString(); if (Linkify.containsUnsupportedCharacters(textString)) { // Do not apply links to text containing unsupported characters. android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return TextLinks.STATUS_NO_LINKS_APPLIED; } if (!textString.startsWith(textLinks.getText())) { return TextLinks.STATUS_DIFFERENT_TEXT; } Loading
core/java/android/widget/SelectionActionModeHelper.java +7 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.TextUtils; import android.text.util.Linkify; import android.util.Log; import android.view.ActionMode; import android.view.textclassifier.SelectionEvent; Loading Loading @@ -1045,7 +1046,12 @@ public final class SelectionActionModeHelper { trimText(); final TextClassification classification; if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { if (Linkify.containsUnsupportedCharacters(mText)) { // Do not show smart actions for text containing unsupported characters. android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); classification = TextClassification.EMPTY; } else if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { final TextClassification.Request request = new TextClassification.Request.Builder( mTrimmedText, mRelativeStart, mRelativeEnd) Loading
core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ import android.service.textclassifier.TextClassifierService; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.Spannable; import android.text.SpannableString; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; Loading Loading @@ -306,6 +308,16 @@ public class TextClassificationManagerTest { mClassifier.generateLinks(request); } @Test public void testApplyLinks_unsupportedCharacter() { if (isTextClassifierDisabled()) return; Spannable url = new SpannableString("\u202Emoc.diordna.com"); TextLinks.Request request = new TextLinks.Request.Builder(url).build(); assertEquals( TextLinks.STATUS_NO_LINKS_APPLIED, mClassifier.generateLinks(request).apply(url, 0, null)); } @Test public void testSetTextClassifier() { TextClassifier classifier = mock(TextClassifier.class); Loading