diff options
author | linyuh <linyuh@google.com> | 2018-05-31 20:59:05 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-06-01 18:19:51 -0700 |
commit | f85644637b808d6a88886e462c1f8fd5f53a6f2f (patch) | |
tree | 6ed1c44ef3a167b27693831b00037db65b8f056c /java/com/android/dialer/i18n | |
parent | f0d515573aa65c265ccb104ca982a5ccfbd0fa24 (diff) |
Solve BiDi problem when phone number is concatenated with RTL-string
Solves BiDi problem that might cause phone number to be displayed
incorrectly in the dialer. Issue might occur when a phone number
is concatenated with a custom number label containing an RTL-string.
Solved by changing affected labels from TextView to BidiTextView.
Removed function spanDisplayNumber in BottomRow which are now obsolete.
Updates the DialerBidiFormatter to prevent whitespace to be misplaced
within a BidiTextView.
BUG=78464687
TEST=Manual
Public-Origin-Change-Id: I789a6f76a5ca805c03a437813ce627eef7a0bf2e
Signed-off-by: Linyu He <linyuh@google.com>
Author: Torbjorn Eklund <torbjorn.eklund@sony.com>
Bug: 78464687
Test: Manual
PiperOrigin-RevId: 198823629
Change-Id: Id35c3ebf514609b4a1fe10a7ae5a297bde7c7456
Diffstat (limited to 'java/com/android/dialer/i18n')
-rw-r--r-- | java/com/android/dialer/i18n/DialerBidiFormatter.java | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/java/com/android/dialer/i18n/DialerBidiFormatter.java b/java/com/android/dialer/i18n/DialerBidiFormatter.java index 4ebaa666c..e882e06c4 100644 --- a/java/com/android/dialer/i18n/DialerBidiFormatter.java +++ b/java/com/android/dialer/i18n/DialerBidiFormatter.java @@ -26,6 +26,7 @@ import com.google.auto.value.AutoValue; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * An enhanced version of {@link BidiFormatter} that can recognize a formatted phone number @@ -40,6 +41,9 @@ public final class DialerBidiFormatter { private DialerBidiFormatter() {} + // Regular expression that matches a single space in the beginning or end of a string. + private static final String REGEXP_SURROUNDING_SPACE = "^[ ]|[ ]$"; + /** * Divides the given text into segments, applies {@link BidiFormatter#unicodeWrap(CharSequence)} * to each segment, and then reassembles the text. @@ -65,19 +69,49 @@ public final class DialerBidiFormatter { } /** - * Segments the given text using {@link Patterns#PHONE}. + * Segments the given text into a sequence of substrings using the following procedure. + * + * <ol> + * <li>Separate text matching {@link Patterns#PHONE} from others. + * <p>For example: "Mobile, +1 650-253-0000, 20 seconds" will be segmented into<br> + * {"Mobile, ", "+1 650-253-0000", ", 20 seconds"} + * <li>For each substring produced by the previous step, separate a single whitespace at the + * start/end of it from the rest of the substring. + * <p>For example, the first substring "Mobile, " will be segmented into {"Mobile,", " "}. + * </ol> + * + * <p>The final result of segmenting "Mobile, +1 650-253-0000, 20 seconds" is<br> + * {"Mobile,", " ", "+1 650-253-0000", ", 20 seconds"}. * - * <p>For example, "Mobile, +1 650-253-0000, 20 seconds" will be segmented into {"Mobile, ", "+1 - * 650-253-0000", ", 20 seconds"}. + * <p>The reason for singling out the whitespace at the start/end of a substring is to prevent it + * from being misplaced in RTL context. */ @VisibleForTesting static List<CharSequence> segmentText(CharSequence text) { Assert.checkArgument(!TextUtils.isEmpty(text)); + // Separate text matching the phone number pattern from others. + List<CharSequence> segmentsSeparatingPhoneNumbers = segmentText(text, Patterns.PHONE); + + // For each substring, separate a single whitespace at the start/end of it from the rest of the + // substring. + List<CharSequence> finalSegments = new ArrayList<>(); + Pattern patternSurroundingSpace = Pattern.compile(REGEXP_SURROUNDING_SPACE); + for (CharSequence segment : segmentsSeparatingPhoneNumbers) { + finalSegments.addAll(segmentText(segment, patternSurroundingSpace)); + } + + return finalSegments; + } + + /** Segments the given text into a sequence of substrings using the provided pattern. */ + private static List<CharSequence> segmentText(CharSequence text, Pattern pattern) { + Assert.checkArgument(!TextUtils.isEmpty(text)); + List<CharSequence> segments = new ArrayList<>(); - // Find the start index and the end index of each segment matching the phone number pattern. - Matcher matcher = Patterns.PHONE.matcher(text.toString()); + // Find the start index and the end index of each segment matching the pattern. + Matcher matcher = pattern.matcher(text.toString()); List<Range> segmentRanges = new ArrayList<>(); while (matcher.find()) { segmentRanges.add(Range.newBuilder().setStart(matcher.start()).setEnd(matcher.end()).build()); |