Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8564463 authored by linyuh's avatar linyuh Committed by Copybara-Service
Browse files

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: default avatarLinyu He <linyuh@google.com>
Author: Torbjorn Eklund <torbjorn.eklund@sony.com>
Bug: 78464687
Test: Manual
PiperOrigin-RevId: 198823629
Change-Id: Id35c3ebf514609b4a1fe10a7ae5a297bde7c7456
parent f0d51557
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@
          android:textColor="?android:attr/textColorPrimaryInverse"
          android:textSize="@dimen/call_composer_name_text_size"/>

        <TextView
        <com.android.dialer.widget.BidiTextView
          android:id="@+id/phone_number"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ public class CallDetailsHeaderViewHolder extends RecyclerView.ViewHolder
  private final CallDetailsHeaderListener callDetailsHeaderListener;
  private final ImageView callbackButton;
  private final BidiTextView nameView;
  private final TextView numberView;
  private final BidiTextView numberView;
  private final TextView networkView;
  private final QuickContactBadge contactPhoto;
  private final Context context;
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/photo_text_margin"/>

    <TextView
    <com.android.dialer.widget.BidiTextView
        android:id="@+id/phone_number"
        style="@style/Dialer.TextAppearance.Secondary.Ellipsize"
        android:layout_width="wrap_content"
+39 −5
Original line number Diff line number Diff line
@@ -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());
Loading