From f85644637b808d6a88886e462c1f8fd5f53a6f2f Mon Sep 17 00:00:00 2001 From: linyuh Date: Thu, 31 May 2018 20:59:05 -0700 Subject: 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 Author: Torbjorn Eklund Bug: 78464687 Test: Manual PiperOrigin-RevId: 198823629 Change-Id: Id35c3ebf514609b4a1fe10a7ae5a297bde7c7456 --- .../dialer/callcomposer/CallComposerActivity.java | 3 +- .../res/layout/call_composer_activity.xml | 2 +- .../calldetails/CallDetailsHeaderViewHolder.java | 2 +- .../calldetails/res/layout/contact_container.xml | 2 +- .../android/dialer/i18n/DialerBidiFormatter.java | 44 +++++++++++++++++++--- java/com/android/dialer/widget/DialerToolbar.java | 4 +- .../dialer/widget/res/layout/dialer_toolbar.xml | 2 +- .../android/incallui/contactgrid/BottomRow.java | 13 +------ .../incallui/contactgrid/ContactGridManager.java | 3 +- .../res/layout/incall_contactgrid_bottom_row.xml | 2 +- 10 files changed, 52 insertions(+), 25 deletions(-) mode change 100644 => 100755 java/com/android/dialer/calldetails/res/layout/contact_container.xml mode change 100644 => 100755 java/com/android/dialer/widget/res/layout/dialer_toolbar.xml diff --git a/java/com/android/dialer/callcomposer/CallComposerActivity.java b/java/com/android/dialer/callcomposer/CallComposerActivity.java index 49bc29c34..921bbbaea 100644 --- a/java/com/android/dialer/callcomposer/CallComposerActivity.java +++ b/java/com/android/dialer/callcomposer/CallComposerActivity.java @@ -78,6 +78,7 @@ import com.android.dialer.storage.StorageComponent; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.UriUtils; import com.android.dialer.util.ViewUtil; +import com.android.dialer.widget.BidiTextView; import com.android.dialer.widget.DialerToolbar; import com.android.dialer.widget.LockableViewPager; import com.android.incallui.callpending.CallPendingActivity; @@ -135,7 +136,7 @@ public class CallComposerActivity extends AppCompatActivity private Long sessionId = Session.NO_SESSION_ID; private TextView nameView; - private TextView numberView; + private BidiTextView numberView; private QuickContactBadge contactPhoto; private RelativeLayout contactContainer; private DialerToolbar toolbar; diff --git a/java/com/android/dialer/callcomposer/res/layout/call_composer_activity.xml b/java/com/android/dialer/callcomposer/res/layout/call_composer_activity.xml index 49d278f30..8b982b9dc 100644 --- a/java/com/android/dialer/callcomposer/res/layout/call_composer_activity.xml +++ b/java/com/android/dialer/callcomposer/res/layout/call_composer_activity.xml @@ -57,7 +57,7 @@ android:textColor="?android:attr/textColorPrimaryInverse" android:textSize="@dimen/call_composer_name_text_size"/> - - + *
  • Separate text matching {@link Patterns#PHONE} from others. + *

    For example: "Mobile, +1 650-253-0000, 20 seconds" will be segmented into
    + * {"Mobile, ", "+1 650-253-0000", ", 20 seconds"} + *

  • For each substring produced by the previous step, separate a single whitespace at the + * start/end of it from the rest of the substring. + *

    For example, the first substring "Mobile, " will be segmented into {"Mobile,", " "}. + * + * + *

    The final result of segmenting "Mobile, +1 650-253-0000, 20 seconds" is
    + * {"Mobile,", " ", "+1 650-253-0000", ", 20 seconds"}. * - *

    For example, "Mobile, +1 650-253-0000, 20 seconds" will be segmented into {"Mobile, ", "+1 - * 650-253-0000", ", 20 seconds"}. + *

    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 segmentText(CharSequence text) { Assert.checkArgument(!TextUtils.isEmpty(text)); + // Separate text matching the phone number pattern from others. + List 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 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 segmentText(CharSequence text, Pattern pattern) { + Assert.checkArgument(!TextUtils.isEmpty(text)); + List 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 segmentRanges = new ArrayList<>(); while (matcher.find()) { segmentRanges.add(Range.newBuilder().setStart(matcher.start()).setEnd(matcher.end()).build()); diff --git a/java/com/android/dialer/widget/DialerToolbar.java b/java/com/android/dialer/widget/DialerToolbar.java index 02ec8c02c..40dabe8bc 100644 --- a/java/com/android/dialer/widget/DialerToolbar.java +++ b/java/com/android/dialer/widget/DialerToolbar.java @@ -29,13 +29,13 @@ import com.android.dialer.theme.base.ThemeComponent; public class DialerToolbar extends Toolbar { private final TextView title; - private final TextView subtitle; + private final BidiTextView subtitle; public DialerToolbar(Context context, @Nullable AttributeSet attributeSet) { super(context, attributeSet); inflate(context, R.layout.dialer_toolbar, this); title = (TextView) findViewById(R.id.title); - subtitle = (TextView) findViewById(R.id.subtitle); + subtitle = (BidiTextView) findViewById(R.id.subtitle); setElevation(getResources().getDimensionPixelSize(R.dimen.toolbar_elevation)); setBackgroundColor(ThemeComponent.get(context).theme().getColorPrimary()); diff --git a/java/com/android/dialer/widget/res/layout/dialer_toolbar.xml b/java/com/android/dialer/widget/res/layout/dialer_toolbar.xml old mode 100644 new mode 100755 index a75176a22..3b4d1367e --- a/java/com/android/dialer/widget/res/layout/dialer_toolbar.xml +++ b/java/com/android/dialer/widget/res/layout/dialer_toolbar.xml @@ -31,7 +31,7 @@ android:textColor="?android:attr/textColorPrimaryInverse" style="@style/Dialer.TextAppearance.Header2"/> - -