ContentViewScrollingTest.java revision 1e9bf3e0803691d0a228da41fc608347b6db4340
1a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// Use of this source code is governed by a BSD-style license that can be
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// found in the LICENSE file.
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell
54ee451de366474b9c228b4e5fa573795a715216dChris Lattnerpackage org.chromium.content.browser;
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner
7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukmanimport android.content.res.Configuration;
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswellimport android.graphics.Canvas;
9a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport android.test.suitebuilder.annotation.SmallTest;
10a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport android.view.KeyEvent;
11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruthimport android.view.MotionEvent;
12a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport android.view.View;
13a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich
14a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport org.chromium.base.test.util.Feature;
15a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport org.chromium.base.test.util.UrlUtils;
16a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport org.chromium.content.browser.ContentViewCore.InternalAccessDelegate;
17a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichimport org.chromium.content.browser.test.util.Criteria;
181222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesenimport org.chromium.content.browser.test.util.CriteriaHelper;
191222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesenimport org.chromium.content_shell_apk.ContentShellTestBase;
201222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesen
21fae02a2ab19abdf12854356e19aeb1da62a0b8eaLang Hames/*
22a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich * Tests that we can scroll and fling a ContentView running inside ContentShell.
23a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich */
24a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarichpublic class ContentViewScrollingTest extends ContentShellTestBase {
25a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich
26a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich    private static final String LARGE_PAGE = UrlUtils.encodeHtmlDataUri(
27a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands            "<html><head>" +
281222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesen            "<meta name=\"viewport\" content=\"width=device-width, " +
291222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesen            "initial-scale=2.0, maximum-scale=2.0\" />" +
301222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesen            "<style>body { width: 5000px; height: 5000px; }</style></head>" +
31a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich            "<body>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</body>" +
32a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich            "</html>");
33a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands
34b126d0530d48890e1689975483b9f923a0fca1daLang Hames    /**
35a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands     * InternalAccessDelegate to ensure AccessibilityEvent notifications (Eg:TYPE_VIEW_SCROLLED)
36a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich     * are being sent properly on scrolling a page.
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    static class TestInternalAccessDelegate implements InternalAccessDelegate {
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40fc0b80d9746e5fd4b45057ab814c67371fb0f9eaEvan Cheng        private boolean mScrollChanged;
41fc0b80d9746e5fd4b45057ab814c67371fb0f9eaEvan Cheng        private final Object mLock = new Object();
42a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands
43a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands
441222287543a5b5917f8c31aa8c88d740f70222d9Jakob Stoklund Olesen
45a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich        @Override
46a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands        public boolean drawChild(Canvas canvas, View child, long drawingTime) {
47b126d0530d48890e1689975483b9f923a0fca1daLang Hames            return false;
48a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands        }
49a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands
50a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands        @Override
51b126d0530d48890e1689975483b9f923a0fca1daLang Hames        public boolean super_onKeyUp(int keyCode, KeyEvent event) {
52a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich            return false;
53a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands        }
54a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands
55fc0b80d9746e5fd4b45057ab814c67371fb0f9eaEvan Cheng        @Override
56a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands        public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
57a5fec0dba34206274041543b5924d2565fb10f9bDuncan Sands            return false;
58a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich        }
59a474685d069a900ab931ee1540c9a79fdd6607a9Cameron Zwarich
60        @Override
61        public boolean super_dispatchKeyEvent(KeyEvent event) {
62            return false;
63        }
64
65        @Override
66        public boolean super_onGenericMotionEvent(MotionEvent event) {
67            return false;
68        }
69
70        @Override
71        public void super_onConfigurationChanged(Configuration newConfig) {
72        }
73
74        @Override
75        public void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix) {
76            synchronized (mLock) {
77                mScrollChanged = true;
78            }
79        }
80
81        @Override
82        public boolean awakenScrollBars() {
83            return false;
84        }
85
86        @Override
87        public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
88            return false;
89        }
90
91        /**
92         * @return Whether OnScrollChanged() has been called.
93         */
94        public boolean isScrollChanged() {
95            synchronized (mLock) {
96                return mScrollChanged;
97            }
98        }
99    }
100
101    private void assertWaitForScroll(final boolean hugLeft, final boolean hugTop)
102            throws InterruptedException {
103        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
104            @Override
105            public boolean isSatisfied() {
106                // Scrolling and flinging don't result in exact coordinates.
107                final int MIN_THRESHOLD = 5;
108                final int MAX_THRESHOLD = 100;
109
110                boolean xCorrect = hugLeft ?
111                        getContentViewCore().getNativeScrollXForTest() < MIN_THRESHOLD :
112                        getContentViewCore().getNativeScrollXForTest() > MAX_THRESHOLD;
113                boolean yCorrect = hugTop ?
114                        getContentViewCore().getNativeScrollYForTest() < MIN_THRESHOLD :
115                        getContentViewCore().getNativeScrollYForTest() > MAX_THRESHOLD;
116                return xCorrect && yCorrect;
117            }
118        }));
119    }
120
121    private void fling(final int vx, final int vy) throws Throwable {
122        runTestOnUiThread(new Runnable() {
123            @Override
124            public void run() {
125                getContentView().fling(System.currentTimeMillis(), 0, 0, vx, vy);
126            }
127        });
128    }
129
130    private void scrollTo(final int x, final int y) throws Throwable {
131        runTestOnUiThread(new Runnable() {
132            @Override
133            public void run() {
134                getContentView().scrollTo(x, y);
135            }
136        });
137    }
138
139    @Override
140    protected void setUp() throws Exception {
141        super.setUp();
142
143        launchContentShellWithUrl(LARGE_PAGE);
144        assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
145        assertWaitForPageScaleFactorMatch(2.0f);
146
147        assertEquals(0, getContentViewCore().getNativeScrollXForTest());
148        assertEquals(0, getContentViewCore().getNativeScrollYForTest());
149    }
150
151    @SmallTest
152    @Feature({"Main"})
153    public void testFling() throws Throwable {
154        // Vertical fling to lower-left.
155        fling(0, -1000);
156        assertWaitForScroll(true, false);
157
158        // Horizontal fling to lower-right.
159        fling(-1000, 0);
160        assertWaitForScroll(false, false);
161
162        // Vertical fling to upper-right.
163        fling(0, 1000);
164        assertWaitForScroll(false, true);
165
166        // Horizontal fling to top-left.
167        fling(1000, 0);
168        assertWaitForScroll(true, true);
169
170        // Diagonal fling to bottom-right.
171        fling(-1000, -1000);
172        assertWaitForScroll(false, false);
173    }
174
175    @SmallTest
176    @Feature({"Main"})
177    public void testScroll() throws Throwable {
178        // Vertical scroll to lower-left.
179        scrollTo(0, 2500);
180        assertWaitForScroll(true, false);
181
182        // Horizontal scroll to lower-right.
183        scrollTo(2500, 2500);
184        assertWaitForScroll(false, false);
185
186        // Vertical scroll to upper-right.
187        scrollTo(2500, 0);
188        assertWaitForScroll(false, true);
189
190        // Horizontal scroll to top-left.
191        scrollTo(0, 0);
192        assertWaitForScroll(true, true);
193
194        // Diagonal scroll to bottom-right.
195        scrollTo(2500, 2500);
196        assertWaitForScroll(false, false);
197    }
198
199    /**
200     * To ensure the AccessibilityEvent notifications (Eg:TYPE_VIEW_SCROLLED) are being sent
201     * properly on scrolling a page.
202     */
203    @SmallTest
204    @Feature({"Main"})
205    public void testOnScrollChanged() throws Throwable {
206        final int scrollToX = 2500;
207        final int scrollToY = 2500;
208        final TestInternalAccessDelegate containerViewInternals = new TestInternalAccessDelegate();
209        runTestOnUiThread(new Runnable() {
210            @Override
211            public void run() {
212                getContentViewCore().setContainerViewInternals(containerViewInternals);
213            }
214        });
215        scrollTo(scrollToX, scrollToY);
216        assertWaitForScroll(false, false);
217        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
218            @Override
219            public boolean isSatisfied() {
220                return containerViewInternals.isScrollChanged();
221            }
222        }));
223    }
224}
225