LinkAccessibilityHelperTest.java revision 7c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14ad
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
19d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.graphics.Rect;
20d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.os.Bundle;
217c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lamimport android.support.v4.text.BidiFormatter;
22d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
23d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.support.v4.widget.ExploreByTouchHelper;
24d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.test.AndroidTestCase;
25d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.test.suitebuilder.annotation.SmallTest;
26d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.SpannableStringBuilder;
27059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lamimport android.util.DisplayMetrics;
28059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lamimport android.util.TypedValue;
297c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lamimport android.view.View;
30d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.view.accessibility.AccessibilityEvent;
31d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.widget.TextView;
32d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
33d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport com.android.setupwizardlib.span.LinkSpan;
34d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport com.android.setupwizardlib.util.LinkAccessibilityHelper;
35d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
36d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.ArrayList;
37d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.Collections;
38d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.List;
39d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
40d832154e333a3a45b5faecd518b664ddd297183cMaurice Lampublic class LinkAccessibilityHelperTest extends AndroidTestCase {
41d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
427c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    private static final LinkSpan LINK_SPAN = new LinkSpan("foobar");
437c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
44d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    private TextView mTextView;
45d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    private TestLinkAccessibilityHelper mHelper;
46d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
47059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam    private DisplayMetrics mDisplayMetrics;
48059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam
49d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    @SmallTest
50d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testGetVirtualViewAt() {
517c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
52059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam        final int virtualViewId = mHelper.getVirtualViewAt(dp2Px(15), dp2Px(10));
53d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("Virtual view ID should be 1", 1, virtualViewId);
54d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
55d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
56d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    @SmallTest
57d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testGetVirtualViewAtHost() {
587c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
59059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam        final int virtualViewId = mHelper.getVirtualViewAt(dp2Px(100), dp2Px(100));
60d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("Virtual view ID should be INVALID_ID",
61d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                ExploreByTouchHelper.INVALID_ID, virtualViewId);
62d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
63d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
64d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    @SmallTest
65d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testGetVisibleVirtualViews() {
667c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
67d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        List<Integer> virtualViewIds = new ArrayList<>();
68d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        mHelper.getVisibleVirtualViews(virtualViewIds);
69d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
70d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("VisibleVirtualViews should be [1]",
71d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                Collections.singletonList(1), virtualViewIds);
72d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
73d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
74d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    @SmallTest
75d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testOnPopulateEventForVirtualView() {
767c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
77d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        AccessibilityEvent event = AccessibilityEvent.obtain();
78d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        mHelper.onPopulateEventForVirtualView(1, event);
79d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
80d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        // LinkSpan is set on substring(1, 2) of "Hello world" --> "e"
81d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("LinkSpan description should be \"e\"",
82d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                "e", event.getContentDescription().toString());
83d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
84d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        event.recycle();
85d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
86d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
87d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    @SmallTest
88d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testOnPopulateEventForVirtualViewHost() {
897c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
90d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        AccessibilityEvent event = AccessibilityEvent.obtain();
91d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        mHelper.onPopulateEventForVirtualView(ExploreByTouchHelper.INVALID_ID, event);
92d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
93d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("Host view description should be \"Hello world\"", "Hello world",
94d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                event.getContentDescription().toString());
95d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
96d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        event.recycle();
97d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
98d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
99d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    @SmallTest
100d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testOnPopulateNodeForVirtualView() {
1017c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
102d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
103d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        mHelper.onPopulateNodeForVirtualView(1, info);
104d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
105d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("LinkSpan description should be \"e\"",
106d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                "e", info.getContentDescription().toString());
107d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertTrue("LinkSpan should be focusable", info.isFocusable());
108d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertTrue("LinkSpan should be clickable", info.isClickable());
109d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        Rect bounds = new Rect();
110d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        info.getBoundsInParent(bounds);
111059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam        assertEquals("LinkSpan bounds should be (10.5dp, 0dp, 18.5dp, 20.5dp)",
112059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam                new Rect(dp2Px(10.5f), dp2Px(0f), dp2Px(18.5f), dp2Px(20.5f)), bounds);
113d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
114d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        info.recycle();
115d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
116d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
117cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam    @SmallTest
118cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam    public void testNullLayout() {
1197c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView();
120cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        // Setting the padding will cause the layout to be null-ed out.
121cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        mTextView.setPadding(1, 1, 1, 1);
122cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam
123cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
124cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        mHelper.onPopulateNodeForVirtualView(0, info);
125cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam
126cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        Rect bounds = new Rect();
127cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        info.getBoundsInParent(bounds);
128cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        assertEquals("LinkSpan bounds should be (0, 0, 1, 1)",
129cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam                new Rect(0, 0, 1, 1), bounds);
130cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam
131cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam        info.recycle();
132cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam    }
133cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam
13404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam    @SmallTest
13504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam    public void testRtlLayout() {
13604eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("מכונה בתרגום");
1377c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        ssb.setSpan(LINK_SPAN, 1, 2, 0 /* flags */);
1387c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView(ssb);
13904eecdd42f0bc9751825f9f21131a59852256278Maurice Lam
14004eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
14104eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        mHelper.onPopulateNodeForVirtualView(1, info);
14204eecdd42f0bc9751825f9f21131a59852256278Maurice Lam
14304eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        assertEquals("LinkSpan description should be \"כ\"",
14404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam                "כ", info.getContentDescription().toString());
14504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        Rect bounds = new Rect();
14604eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        info.getBoundsInParent(bounds);
1477c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan bounds should be (481.5dp, 0dp, 489.5dp, 20.5dp)",
1487c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                new Rect(dp2Px(481.5f), dp2Px(0f), dp2Px(489.5f), dp2Px(20.5f)), bounds);
1497c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1507c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        info.recycle();
1517c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    }
1527c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1537c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    @SmallTest
1547c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    public void testMultilineLink() {
1557c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder(
1567c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
1577c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                + "Praesent accumsan efficitur eros eu porttitor.");
1587c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        ssb.setSpan(LINK_SPAN, 51, 74, 0 /* flags */);
1597c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView(ssb);
1607c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1617c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
1627c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mHelper.onPopulateNodeForVirtualView(51, info);
1637c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1647c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan description should match the span",
1657c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                "elit. Praesent accumsan", info.getContentDescription().toString());
1667c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        Rect bounds = new Rect();
1677c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        info.getBoundsInParent(bounds);
1687c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan bounds should match first line of the span",
1697c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                new Rect(dp2Px(343f), dp2Px(0f), dp2Px(500f), dp2Px(19.5f)), bounds);
1707c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1717c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        info.recycle();
1727c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    }
1737c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1747c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    @SmallTest
1757c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    public void testRtlMultilineLink() {
1767c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        String iwLoremIpsum = "אחר על רביעי אקטואליה. לוח דת אחרות המקובל רומנית, מיזמים מועמדים "
1777c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                + "האנציקלופדיה בה צ'ט. מתן מה שנורו לערוך ייִדיש, בקר או החול אנתרופולוגיה, עוד "
1787c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                + "דפים המחשב מיזמים ב.";
1797c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder(iwLoremIpsum);
1807c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        ssb.setSpan(LINK_SPAN, 50, 100, 0 /* flags */);
1817c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView(ssb);
1827c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1837c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
1847c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mHelper.onPopulateNodeForVirtualView(50, info);
1857c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
1867c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan description should match the span",
1877c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                iwLoremIpsum.substring(50, 100),
1887c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                info.getContentDescription().toString());
1897c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        Rect bounds = new Rect();
1907c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        info.getBoundsInParent(bounds);
1917c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan bounds should match the first line of the span",
1927c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                new Rect(dp2Px(0f), dp2Px(0f), dp2Px(150f), dp2Px(19.5f)), bounds);
19304eecdd42f0bc9751825f9f21131a59852256278Maurice Lam
19404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam        info.recycle();
19504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam    }
19604eecdd42f0bc9751825f9f21131a59852256278Maurice Lam
1977c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    @SmallTest
1987c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    public void testBidiMultilineLink() {
1997c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        String iwLoremIpsum = "אחר על רביעי אקטואליה. לוח דת אחרות המקובל רומנית, מיזמים מועמדים "
2007c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                + "האנציקלופדיה בה צ'ט. מתן מה שנורו לערוך ייִדיש, בקר או החול אנתרופולוגיה, עוד "
2017c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                + "דפים המחשב מיזמים ב.";
2027c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        BidiFormatter formatter = BidiFormatter.getInstance(false /* rtlContext */);
2037c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder();
2047c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        ssb.append("hello ").append(formatter.unicodeWrap(iwLoremIpsum)).append(" world");
2057c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        ssb.setSpan(LINK_SPAN,
2067c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                "hello ".length() + 2, // Add two for the characters added by BidiFormatter
2077c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                "hello ".length() + 2 + iwLoremIpsum.length(),
2087c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                0 /* flags */);
2097c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView(ssb);
2107c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
2117c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
2127c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mHelper.onPopulateNodeForVirtualView("hello ".length() + 2, info);
2137c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
2147c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan description should match the span",
2157c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                iwLoremIpsum,
2167c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                info.getContentDescription().toString());
2177c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        Rect bounds = new Rect();
2187c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        info.getBoundsInParent(bounds);
2197c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        assertEquals("LinkSpan bounds should match the first line of the span",
2207c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                new Rect(dp2Px(491.5f), dp2Px(0f), dp2Px(500f), dp2Px(19.5f)), bounds);
2217c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
2227c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        info.recycle();
2237c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    }
2247c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
2257c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    private void initTextView() {
2267c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
2277c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        ssb.setSpan(LINK_SPAN, 1, 2, 0 /* flags */);
2287c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        initTextView(ssb);
2297c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    }
2307c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
2317c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    private void initTextView(CharSequence text) {
2327c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mTextView = new TextView(getContext());
2337c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mTextView.setSingleLine(false);
2347c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mTextView.setText(text);
2357c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
2367c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mHelper = new TestLinkAccessibilityHelper(mTextView);
2377c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
2387c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        int measureExactly500dp = View.MeasureSpec.makeMeasureSpec(dp2Px(500),
2397c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam                View.MeasureSpec.EXACTLY);
2407c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mTextView.measure(measureExactly500dp, measureExactly500dp);
2417c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam        mTextView.layout(dp2Px(0), dp2Px(0), dp2Px(500), dp2Px(500));
2427c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam    }
2437c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam
244059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam    private int dp2Px(float dp) {
245059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam        if (mDisplayMetrics == null) {
246059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam            mDisplayMetrics = getContext().getResources().getDisplayMetrics();
247059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam        }
248059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mDisplayMetrics);
249059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam    }
250059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam
251d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    private static class TestLinkAccessibilityHelper extends LinkAccessibilityHelper {
252d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
253d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        public TestLinkAccessibilityHelper(TextView view) {
254d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam            super(view);
255d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        }
256d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
257d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        @Override
258d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        public int getVirtualViewAt(float x, float y) {
259d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam            return super.getVirtualViewAt(x, y);
260d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        }
261d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
262d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        @Override
263d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        public void getVisibleVirtualViews(List<Integer> virtualViewIds) {
264d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam            super.getVisibleVirtualViews(virtualViewIds);
265d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        }
266d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
267d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        @Override
268d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        public void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
269d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam            super.onPopulateEventForVirtualView(virtualViewId, event);
270d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        }
271d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
272d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        @Override
273d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        public void onPopulateNodeForVirtualView(int virtualViewId,
274d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                AccessibilityNodeInfoCompat info) {
275d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam            super.onPopulateNodeForVirtualView(virtualViewId, info);
276d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        }
277d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
278d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        @Override
279d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        public boolean onPerformActionForVirtualView(int virtualViewId, int action,
280d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                Bundle arguments) {
281d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam            return super.onPerformActionForVirtualView(virtualViewId, action, arguments);
282d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        }
283d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
284d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam}
285