LinkAccessibilityHelperTest.java revision 2614260933341bd4ea7bb37a3435f46f82cacef7
1d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam/* 2d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Copyright (C) 2016 The Android Open Source Project 3d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 4d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 5d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * you may not use this file except in compliance with the License. 6d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * You may obtain a copy of the License at 7d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 8d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * http://www.apache.org/licenses/LICENSE-2.0 9d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 10d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Unless required by applicable law or agreed to in writing, software 11d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 12d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * See the License for the specific language governing permissions and 14d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * limitations under the License. 15d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam */ 16d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 17d832154e333a3a45b5faecd518b664ddd297183cMaurice Lampackage com.android.setupwizardlib.test; 18d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 192614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertEquals; 202614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertTrue; 212614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam 22d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.graphics.Rect; 23d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.os.Bundle; 242614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport android.support.test.InstrumentationRegistry; 252614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport android.support.test.filters.SmallTest; 262614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport android.support.test.runner.AndroidJUnit4; 277c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lamimport android.support.v4.text.BidiFormatter; 28d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 29d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.support.v4.widget.ExploreByTouchHelper; 30d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.SpannableStringBuilder; 31059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lamimport android.util.DisplayMetrics; 32059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lamimport android.util.TypedValue; 337c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lamimport android.view.View; 34d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.view.accessibility.AccessibilityEvent; 35d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.widget.TextView; 36d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 37d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport com.android.setupwizardlib.span.LinkSpan; 38d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport com.android.setupwizardlib.util.LinkAccessibilityHelper; 39d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 402614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport org.junit.Test; 412614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport org.junit.runner.RunWith; 422614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam 43d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.ArrayList; 44d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.Collections; 45d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.List; 46d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 472614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam@RunWith(AndroidJUnit4.class) 482614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam@SmallTest 492614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lampublic class LinkAccessibilityHelperTest { 50d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 517c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam private static final LinkSpan LINK_SPAN = new LinkSpan("foobar"); 527c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 53d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam private TextView mTextView; 54d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam private TestLinkAccessibilityHelper mHelper; 55d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 56059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam private DisplayMetrics mDisplayMetrics; 57059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam 582614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 59d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testGetVirtualViewAt() { 607c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 61059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam final int virtualViewId = mHelper.getVirtualViewAt(dp2Px(15), dp2Px(10)); 62d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("Virtual view ID should be 1", 1, virtualViewId); 63d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 64d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 652614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 66d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testGetVirtualViewAtHost() { 677c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 68059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam final int virtualViewId = mHelper.getVirtualViewAt(dp2Px(100), dp2Px(100)); 69d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("Virtual view ID should be INVALID_ID", 70d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam ExploreByTouchHelper.INVALID_ID, virtualViewId); 71d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 72d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 732614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 74d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testGetVisibleVirtualViews() { 757c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 76d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam List<Integer> virtualViewIds = new ArrayList<>(); 77d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam mHelper.getVisibleVirtualViews(virtualViewIds); 78d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 79d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("VisibleVirtualViews should be [1]", 80d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Collections.singletonList(1), virtualViewIds); 81d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 82d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 832614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 84d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testOnPopulateEventForVirtualView() { 857c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 86d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam AccessibilityEvent event = AccessibilityEvent.obtain(); 87d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam mHelper.onPopulateEventForVirtualView(1, event); 88d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 89d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam // LinkSpan is set on substring(1, 2) of "Hello world" --> "e" 90d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("LinkSpan description should be \"e\"", 91d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam "e", event.getContentDescription().toString()); 92d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 93d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam event.recycle(); 94d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 95d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 962614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 97d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testOnPopulateEventForVirtualViewHost() { 987c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 99d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam AccessibilityEvent event = AccessibilityEvent.obtain(); 100d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam mHelper.onPopulateEventForVirtualView(ExploreByTouchHelper.INVALID_ID, event); 101d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 102d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("Host view description should be \"Hello world\"", "Hello world", 103d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam event.getContentDescription().toString()); 104d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 105d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam event.recycle(); 106d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 107d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 1082614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 109d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testOnPopulateNodeForVirtualView() { 1107c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 111d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 112d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam mHelper.onPopulateNodeForVirtualView(1, info); 113d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 114d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("LinkSpan description should be \"e\"", 115d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam "e", info.getContentDescription().toString()); 116d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertTrue("LinkSpan should be focusable", info.isFocusable()); 117d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertTrue("LinkSpan should be clickable", info.isClickable()); 118d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Rect bounds = new Rect(); 119d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam info.getBoundsInParent(bounds); 120059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam assertEquals("LinkSpan bounds should be (10.5dp, 0dp, 18.5dp, 20.5dp)", 121059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam new Rect(dp2Px(10.5f), dp2Px(0f), dp2Px(18.5f), dp2Px(20.5f)), bounds); 122d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 123d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam info.recycle(); 124d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 125d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 1262614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 127cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam public void testNullLayout() { 1287c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(); 129cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam // Setting the padding will cause the layout to be null-ed out. 130cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mTextView.setPadding(1, 1, 1, 1); 131cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 132cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 133cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mHelper.onPopulateNodeForVirtualView(0, info); 134cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 135cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam Rect bounds = new Rect(); 136cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam info.getBoundsInParent(bounds); 137cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam assertEquals("LinkSpan bounds should be (0, 0, 1, 1)", 138cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam new Rect(0, 0, 1, 1), bounds); 139cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 140cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam info.recycle(); 141cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam } 142cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 1432614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 14404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam public void testRtlLayout() { 14504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("מכונה בתרגום"); 1467c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ssb.setSpan(LINK_SPAN, 1, 2, 0 /* flags */); 1477c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(ssb); 14804eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 14904eecdd42f0bc9751825f9f21131a59852256278Maurice Lam AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 15004eecdd42f0bc9751825f9f21131a59852256278Maurice Lam mHelper.onPopulateNodeForVirtualView(1, info); 15104eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 15204eecdd42f0bc9751825f9f21131a59852256278Maurice Lam assertEquals("LinkSpan description should be \"כ\"", 15304eecdd42f0bc9751825f9f21131a59852256278Maurice Lam "כ", info.getContentDescription().toString()); 15404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam Rect bounds = new Rect(); 15504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam info.getBoundsInParent(bounds); 1567c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan bounds should be (481.5dp, 0dp, 489.5dp, 20.5dp)", 1577c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam new Rect(dp2Px(481.5f), dp2Px(0f), dp2Px(489.5f), dp2Px(20.5f)), bounds); 1587c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1597c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.recycle(); 1607c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1617c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1622614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 1637c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam public void testMultilineLink() { 1647c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder( 1657c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " 1667c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam + "Praesent accumsan efficitur eros eu porttitor."); 1677c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ssb.setSpan(LINK_SPAN, 51, 74, 0 /* flags */); 1687c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(ssb); 1697c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1707c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 1717c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mHelper.onPopulateNodeForVirtualView(51, info); 1727c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1737c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan description should match the span", 1747c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "elit. Praesent accumsan", info.getContentDescription().toString()); 1757c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam Rect bounds = new Rect(); 1767c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.getBoundsInParent(bounds); 1777c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan bounds should match first line of the span", 1787c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam new Rect(dp2Px(343f), dp2Px(0f), dp2Px(500f), dp2Px(19.5f)), bounds); 1797c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1807c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.recycle(); 1817c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1827c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1832614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 1847c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam public void testRtlMultilineLink() { 1857c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam String iwLoremIpsum = "אחר על רביעי אקטואליה. לוח דת אחרות המקובל רומנית, מיזמים מועמדים " 1867c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam + "האנציקלופדיה בה צ'ט. מתן מה שנורו לערוך ייִדיש, בקר או החול אנתרופולוגיה, עוד " 1877c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam + "דפים המחשב מיזמים ב."; 1887c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder(iwLoremIpsum); 1897c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ssb.setSpan(LINK_SPAN, 50, 100, 0 /* flags */); 1907c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(ssb); 1917c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1927c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 1937c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mHelper.onPopulateNodeForVirtualView(50, info); 1947c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1957c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan description should match the span", 1967c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam iwLoremIpsum.substring(50, 100), 1977c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.getContentDescription().toString()); 1987c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam Rect bounds = new Rect(); 1997c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.getBoundsInParent(bounds); 2007c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan bounds should match the first line of the span", 2017c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam new Rect(dp2Px(0f), dp2Px(0f), dp2Px(150f), dp2Px(19.5f)), bounds); 20204eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 20304eecdd42f0bc9751825f9f21131a59852256278Maurice Lam info.recycle(); 20404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam } 20504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 2062614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 2077c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam public void testBidiMultilineLink() { 2087c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam String iwLoremIpsum = "אחר על רביעי אקטואליה. לוח דת אחרות המקובל רומנית, מיזמים מועמדים " 2097c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam + "האנציקלופדיה בה צ'ט. מתן מה שנורו לערוך ייִדיש, בקר או החול אנתרופולוגיה, עוד " 2107c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam + "דפים המחשב מיזמים ב."; 2117c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam BidiFormatter formatter = BidiFormatter.getInstance(false /* rtlContext */); 2127c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder(); 2137c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ssb.append("hello ").append(formatter.unicodeWrap(iwLoremIpsum)).append(" world"); 2147c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ssb.setSpan(LINK_SPAN, 2157c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "hello ".length() + 2, // Add two for the characters added by BidiFormatter 2167c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "hello ".length() + 2 + iwLoremIpsum.length(), 2177c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 0 /* flags */); 2187c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(ssb); 2197c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2207c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(); 2217c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mHelper.onPopulateNodeForVirtualView("hello ".length() + 2, info); 2227c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2237c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan description should match the span", 2247c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam iwLoremIpsum, 2257c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.getContentDescription().toString()); 2267c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam Rect bounds = new Rect(); 2277c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.getBoundsInParent(bounds); 2287c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam assertEquals("LinkSpan bounds should match the first line of the span", 2297c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam new Rect(dp2Px(491.5f), dp2Px(0f), dp2Px(500f), dp2Px(19.5f)), bounds); 2307c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2317c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam info.recycle(); 2327c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2337c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2347c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam private void initTextView() { 2357c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 2367c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ssb.setSpan(LINK_SPAN, 1, 2, 0 /* flags */); 2377c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam initTextView(ssb); 2387c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2397c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2407c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam private void initTextView(CharSequence text) { 2412614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam mTextView = new TextView(InstrumentationRegistry.getContext()); 2427c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mTextView.setSingleLine(false); 2437c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mTextView.setText(text); 2447c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); 2457c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mHelper = new TestLinkAccessibilityHelper(mTextView); 2467c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2477c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam int measureExactly500dp = View.MeasureSpec.makeMeasureSpec(dp2Px(500), 2487c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam View.MeasureSpec.EXACTLY); 2497c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mTextView.measure(measureExactly500dp, measureExactly500dp); 2507c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam mTextView.layout(dp2Px(0), dp2Px(0), dp2Px(500), dp2Px(500)); 2517c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2527c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 253059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam private int dp2Px(float dp) { 254059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam if (mDisplayMetrics == null) { 2552614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam mDisplayMetrics = 2562614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam InstrumentationRegistry.getContext().getResources().getDisplayMetrics(); 257059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam } 258059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mDisplayMetrics); 259059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam } 260059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam 261d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam private static class TestLinkAccessibilityHelper extends LinkAccessibilityHelper { 262d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 263d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public TestLinkAccessibilityHelper(TextView view) { 264d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam super(view); 265d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 266d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 267d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam @Override 268d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public int getVirtualViewAt(float x, float y) { 269d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return super.getVirtualViewAt(x, y); 270d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 271d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 272d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam @Override 273d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void getVisibleVirtualViews(List<Integer> virtualViewIds) { 274d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam super.getVisibleVirtualViews(virtualViewIds); 275d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 276d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 277d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam @Override 278d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) { 279d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam super.onPopulateEventForVirtualView(virtualViewId, event); 280d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 281d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 282d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam @Override 283d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void onPopulateNodeForVirtualView(int virtualViewId, 284d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam AccessibilityNodeInfoCompat info) { 285d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam super.onPopulateNodeForVirtualView(virtualViewId, info); 286d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 287d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 288d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam @Override 289d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public boolean onPerformActionForVirtualView(int virtualViewId, int action, 290d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Bundle arguments) { 291d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return super.onPerformActionForVirtualView(virtualViewId, action, arguments); 292d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 293d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 294d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam} 295