[SuwLib] Tap on list items must always register

When talkback is enabled, sometimes tap on list items does not result in
the whole item being selected by talkback. (No green border around the
item)

- This was caused because focus was enabled on richtextviews by
  ExploreByTouchHelper.
- Fix is to avoid creating LinkAccessibilityHelper when focus is
  disabled and text has no links

bug:29538956
Change-Id: I795a1f621635e8e8e5ee2fa60d2eafc02144b84a
diff --git a/library/eclair-mr1/src/com/android/setupwizardlib/view/RichTextView.java b/library/eclair-mr1/src/com/android/setupwizardlib/view/RichTextView.java
index fc1014a..2931e27 100644
--- a/library/eclair-mr1/src/com/android/setupwizardlib/view/RichTextView.java
+++ b/library/eclair-mr1/src/com/android/setupwizardlib/view/RichTextView.java
@@ -108,8 +108,9 @@
         // Set text first before doing anything else because setMovementMethod internally calls
         // setText. This in turn ends up calling this method with mText as the first parameter
         super.setText(text, type);
+        boolean hasLinks = hasLinks(text);
 
-        if (hasLinks(text)) {
+        if (hasLinks) {
             // When a TextView has a movement method, it will set the view to clickable. This makes
             // View.onTouchEvent always return true and consumes the touch event, essentially
             // nullifying any return values of MovementMethod.onTouchEvent.
@@ -119,6 +120,11 @@
         } else {
             setMovementMethod(null);
         }
+        // ExploreByTouchHelper automatically enables focus for RichTextView
+        // even though it may not have any links. Causes problems during talkback
+        // as individual TextViews consume touch events and thereby reducing the focus window
+        // shown by Talkback. Disable focus if there are no links
+        setFocusable(hasLinks);
     }
 
     private boolean hasLinks(CharSequence text) {
diff --git a/library/eclair-mr1/test/src/com/android/setupwizardlib/test/RichTextViewTest.java b/library/eclair-mr1/test/src/com/android/setupwizardlib/test/RichTextViewTest.java
index c591580..b5bf73e 100644
--- a/library/eclair-mr1/test/src/com/android/setupwizardlib/test/RichTextViewTest.java
+++ b/library/eclair-mr1/test/src/com/android/setupwizardlib/test/RichTextViewTest.java
@@ -72,4 +72,43 @@
         assertTrue("The span should be a TextAppearanceSpan",
                 spans[0] instanceof TextAppearanceSpan);
     }
+
+    @SmallTest
+    public void testTextContaininingLinksAreFocusable() {
+        Annotation testLink = new Annotation("link", "value");
+        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("Linked");
+        spannableStringBuilder.setSpan(testLink, 0, 3, 0);
+
+        RichTextView view = new RichTextView(getContext());
+        view.setText(spannableStringBuilder);
+
+        assertTrue("TextView should be focusable since it contains spans", view.isFocusable());
+    }
+
+
+    @SmallTest
+    public void testTextContainingNoLinksAreNotFocusable() {
+        RichTextView textView = new RichTextView(getContext());
+        textView.setText("Thou shall not be focusable!");
+
+        assertFalse("TextView should not be focusable since it does not contain any span",
+                textView.isFocusable());
+    }
+
+
+    // Based on the text contents of the text view, the "focusable" property of the element
+    // should also be automatically changed.
+    @SmallTest
+    public void testRichTxtViewFocusChangesWithTextChange() {
+        RichTextView textView = new RichTextView(getContext());
+        textView.setText("Thou shall not be focusable!");
+
+        assertFalse(textView.isFocusable());
+
+        SpannableStringBuilder spannableStringBuilder =
+                new SpannableStringBuilder("I am focusable");
+        spannableStringBuilder.setSpan(new Annotation("link", "focus:on_me"), 0, 1, 0);
+        textView.setText(spannableStringBuilder);
+        assertTrue(textView.isFocusable());
+    }
 }