Loading core/java/android/text/util/Linkify.java +36 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,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.webkit.WebView; import android.widget.TextView; Loading Loading @@ -66,6 +67,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 @@ -228,6 +232,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 @@ -273,6 +282,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 @@ -420,6 +452,10 @@ public class Linkify { public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, @Nullable String scheme, @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { if (spannable != null && containsUnsupportedCharacters(spannable.toString())) { android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return false; } return addLinks(spannable, pattern, scheme, null, matchFilter, transformFilter); } Loading core/java/android/view/textclassifier/TextClassification.java +1 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ public final class TextClassification { /** * @hide */ static final TextClassification EMPTY = new TextClassification.Builder().build(); public static final TextClassification EMPTY = new TextClassification.Builder().build(); @NonNull private final String mText; @Nullable private final Drawable mIcon; Loading core/java/android/widget/SelectionActionModeHelper.java +11 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.LocaleList; 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.TextClassification; Loading Loading @@ -692,11 +693,19 @@ final class SelectionActionModeHelper { mLastClassificationLocales = mLocales; trimText(); final TextClassification classification; 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 { classification = mTextClassifier.classifyText( mTrimmedText, mRelativeStart, mRelativeEnd, mLocales); } mLastClassificationResult = new SelectionResult( mSelectionStart, mSelectionEnd, mTextClassifier.classifyText( mTrimmedText, mRelativeStart, mRelativeEnd, mLocales), classification, selection); } Loading core/tests/coretests/src/android/widget/TextViewActivityTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -838,6 +838,19 @@ public class TextViewActivityTest { assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist); } @Test public void testNoAssistItemForTextFieldWithUnsupportedCharacters() throws Throwable { useSystemDefaultTextClassifier(); final String text = "\u202Emoc.diordna.com"; final TextView textView = mActivity.findViewById(R.id.textview); mActivityRule.runOnUiThread(() -> textView.setText(text)); mInstrumentation.waitForIdleSync(); onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('.'))); sleepForFloatingToolbarPopup(); assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist); } @Test public void testPastePlainText_menuAction() { initializeClipboardWithText(TextStyle.STYLED); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +10 −12 Original line number Diff line number Diff line Loading @@ -4353,7 +4353,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { final int realQuality = metrics.quality; if (realQuality < quality && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { Loading @@ -4364,7 +4363,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } quality = Math.max(realQuality, quality); } int length = getPasswordMinimumLength(null, userHandle, /* parent */ false); if (password.length() < length) { Slog.w(LOG_TAG, "resetPassword: password length " + password.length() Loading Loading
core/java/android/text/util/Linkify.java +36 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,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.webkit.WebView; import android.widget.TextView; Loading Loading @@ -66,6 +67,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 @@ -228,6 +232,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 @@ -273,6 +282,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 @@ -420,6 +452,10 @@ public class Linkify { public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, @Nullable String scheme, @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { if (spannable != null && containsUnsupportedCharacters(spannable.toString())) { android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); return false; } return addLinks(spannable, pattern, scheme, null, matchFilter, transformFilter); } Loading
core/java/android/view/textclassifier/TextClassification.java +1 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ public final class TextClassification { /** * @hide */ static final TextClassification EMPTY = new TextClassification.Builder().build(); public static final TextClassification EMPTY = new TextClassification.Builder().build(); @NonNull private final String mText; @Nullable private final Drawable mIcon; Loading
core/java/android/widget/SelectionActionModeHelper.java +11 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.LocaleList; 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.TextClassification; Loading Loading @@ -692,11 +693,19 @@ final class SelectionActionModeHelper { mLastClassificationLocales = mLocales; trimText(); final TextClassification classification; 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 { classification = mTextClassifier.classifyText( mTrimmedText, mRelativeStart, mRelativeEnd, mLocales); } mLastClassificationResult = new SelectionResult( mSelectionStart, mSelectionEnd, mTextClassifier.classifyText( mTrimmedText, mRelativeStart, mRelativeEnd, mLocales), classification, selection); } Loading
core/tests/coretests/src/android/widget/TextViewActivityTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -838,6 +838,19 @@ public class TextViewActivityTest { assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist); } @Test public void testNoAssistItemForTextFieldWithUnsupportedCharacters() throws Throwable { useSystemDefaultTextClassifier(); final String text = "\u202Emoc.diordna.com"; final TextView textView = mActivity.findViewById(R.id.textview); mActivityRule.runOnUiThread(() -> textView.setText(text)); mInstrumentation.waitForIdleSync(); onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('.'))); sleepForFloatingToolbarPopup(); assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist); } @Test public void testPastePlainText_menuAction() { initializeClipboardWithText(TextStyle.STYLED); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +10 −12 Original line number Diff line number Diff line Loading @@ -4353,7 +4353,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { final int realQuality = metrics.quality; if (realQuality < quality && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { Loading @@ -4364,7 +4363,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } quality = Math.max(realQuality, quality); } int length = getPasswordMinimumLength(null, userHandle, /* parent */ false); if (password.length() < length) { Slog.w(LOG_TAG, "resetPassword: password length " + password.length() Loading