[SuwLib] Fix RTL LinkAccessibilityHelper

Adjust the bounds returned by LinkAccessibilityHelper for RTL.

Test: ./gradlew connectedAndroidTest
Bug: 31161044
Bug: 31077012
Change-Id: I63c896c89c0215b9d13b6128bbd06238ed0bf48e
diff --git a/library/eclair-mr1/src/com/android/setupwizardlib/util/LinkAccessibilityHelper.java b/library/eclair-mr1/src/com/android/setupwizardlib/util/LinkAccessibilityHelper.java
index 3e4b7e2..e6fa497 100644
--- a/library/eclair-mr1/src/com/android/setupwizardlib/util/LinkAccessibilityHelper.java
+++ b/library/eclair-mr1/src/com/android/setupwizardlib/util/LinkAccessibilityHelper.java
@@ -179,10 +179,22 @@
                 final int lineStart = layout.getLineForOffset(spanStart);
                 final int lineEnd = layout.getLineForOffset(spanEnd);
                 layout.getLineBounds(lineStart, outRect);
-                outRect.left = (int) xStart;
                 if (lineEnd == lineStart) {
-                    outRect.right = (int) xEnd;
-                } // otherwise just leave it at the end of the start line
+                    // If the span is on a single line, adjust both the left and right bounds
+                    // so outrect is exactly bounding the span.
+                    outRect.left = (int) Math.min(xStart, xEnd);
+                    outRect.right = (int) Math.max(xStart, xEnd);
+                } else {
+                    // If the span wraps across multiple lines, only use the first line (as returned
+                    // by layout.getLineBounds above), and adjust the "start" of outrect to where
+                    // the span starts, leaving the "end" of outrect at the end of the line.
+                    // ("start" being left for LTR, and right for RTL)
+                    if (layout.getParagraphDirection(lineStart) == Layout.DIR_RIGHT_TO_LEFT) {
+                        outRect.right = (int) xStart;
+                    } else {
+                        outRect.left = (int) xStart;
+                    }
+                }
 
                 // Offset for padding
                 outRect.offset(mView.getTotalPaddingLeft(), mView.getTotalPaddingTop());
diff --git a/library/eclair-mr1/test/src/com/android/setupwizardlib/test/LinkAccessibilityHelperTest.java b/library/eclair-mr1/test/src/com/android/setupwizardlib/test/LinkAccessibilityHelperTest.java
index a129f65..76885b9 100644
--- a/library/eclair-mr1/test/src/com/android/setupwizardlib/test/LinkAccessibilityHelperTest.java
+++ b/library/eclair-mr1/test/src/com/android/setupwizardlib/test/LinkAccessibilityHelperTest.java
@@ -137,6 +137,37 @@
         info.recycle();
     }
 
+    @SmallTest
+    public void testRtlLayout() {
+        // Redo setUp with a Hebrew (RTL) string.
+        mSpan = new LinkSpan("foobar");
+        SpannableStringBuilder ssb = new SpannableStringBuilder("מכונה בתרגום");
+        ssb.setSpan(mSpan, 1, 2, 0 /* flags */);
+
+        mTextView = new TextView(getContext());
+        mTextView.setText(ssb);
+        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
+        mHelper = new TestLinkAccessibilityHelper(mTextView);
+
+        mTextView.measure(dp2Px(500), dp2Px(500));
+        mTextView.layout(dp2Px(0), dp2Px(0), dp2Px(500), dp2Px(500));
+        // End redo setup
+
+        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+        mHelper.onPopulateNodeForVirtualView(1, info);
+
+        assertEquals("LinkSpan description should be \"כ\"",
+                "כ", info.getContentDescription().toString());
+        assertTrue("LinkSpan should be focusable", info.isFocusable());
+        assertTrue("LinkSpan should be clickable", info.isClickable());
+        Rect bounds = new Rect();
+        info.getBoundsInParent(bounds);
+        assertEquals("LinkSpan bounds should be (70.5dp, 0dp, 78.5dp, 20.5dp)",
+                new Rect(dp2Px(70.5f), dp2Px(0f), dp2Px(78.5f), dp2Px(20.5f)), bounds);
+
+        info.recycle();
+    }
+
     private int dp2Px(float dp) {
         if (mDisplayMetrics == null) {
             mDisplayMetrics = getContext().getResources().getDisplayMetrics();