1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.content.browser;
7 import android.content.res.Configuration;
8 import android.graphics.Canvas;
9 import android.os.SystemClock;
10 import android.test.suitebuilder.annotation.SmallTest;
11 import android.view.KeyEvent;
12 import android.view.MotionEvent;
13 import android.view.View;
15 import org.chromium.base.test.util.Feature;
16 import org.chromium.base.test.util.UrlUtils;
17 import org.chromium.content.browser.ContentViewCore.InternalAccessDelegate;
18 import org.chromium.content.browser.test.util.Criteria;
19 import org.chromium.content.browser.test.util.CriteriaHelper;
20 import org.chromium.content_shell_apk.ContentShellTestBase;
23 * Tests that we can scroll and fling a ContentView running inside ContentShell.
25 public class ContentViewScrollingTest extends ContentShellTestBase {
27 private static final String LARGE_PAGE = UrlUtils.encodeHtmlDataUri(
29 "<meta name=\"viewport\" content=\"width=device-width, " +
30 "initial-scale=2.0, maximum-scale=2.0\" />" +
31 "<style>body { width: 5000px; height: 5000px; }</style></head>" +
32 "<body>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</body>" +
36 * InternalAccessDelegate to ensure AccessibilityEvent notifications (Eg:TYPE_VIEW_SCROLLED)
37 * are being sent properly on scrolling a page.
39 static class TestInternalAccessDelegate implements InternalAccessDelegate {
41 private boolean mScrollChanged;
42 private final Object mLock = new Object();
47 public boolean drawChild(Canvas canvas, View child, long drawingTime) {
52 public boolean super_onKeyUp(int keyCode, KeyEvent event) {
57 public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
62 public boolean super_dispatchKeyEvent(KeyEvent event) {
67 public boolean super_onGenericMotionEvent(MotionEvent event) {
72 public void super_onConfigurationChanged(Configuration newConfig) {
76 public void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix) {
77 synchronized (mLock) {
78 mScrollChanged = true;
83 public boolean awakenScrollBars() {
88 public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
93 * @return Whether OnScrollChanged() has been called.
95 public boolean isScrollChanged() {
96 synchronized (mLock) {
97 return mScrollChanged;
102 private void assertWaitForScroll(final boolean hugLeft, final boolean hugTop)
103 throws InterruptedException {
104 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
106 public boolean isSatisfied() {
107 // Scrolling and flinging don't result in exact coordinates.
108 final int MIN_THRESHOLD = 5;
109 final int MAX_THRESHOLD = 100;
111 boolean xCorrect = hugLeft ?
112 getContentViewCore().getNativeScrollXForTest() < MIN_THRESHOLD :
113 getContentViewCore().getNativeScrollXForTest() > MAX_THRESHOLD;
114 boolean yCorrect = hugTop ?
115 getContentViewCore().getNativeScrollYForTest() < MIN_THRESHOLD :
116 getContentViewCore().getNativeScrollYForTest() > MAX_THRESHOLD;
117 return xCorrect && yCorrect;
122 private void fling(final int vx, final int vy) throws Throwable {
123 runTestOnUiThread(new Runnable() {
126 getContentViewCore().flingForTest(SystemClock.uptimeMillis(), 0, 0, vx, vy);
131 private void scrollTo(final int x, final int y) throws Throwable {
132 runTestOnUiThread(new Runnable() {
135 getContentViewCore().getContainerView().scrollTo(x, y);
141 protected void setUp() throws Exception {
144 launchContentShellWithUrl(LARGE_PAGE);
145 assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
146 assertWaitForPageScaleFactorMatch(2.0f);
148 assertEquals(0, getContentViewCore().getNativeScrollXForTest());
149 assertEquals(0, getContentViewCore().getNativeScrollYForTest());
154 public void testFling() throws Throwable {
155 // Vertical fling to lower-left.
157 assertWaitForScroll(true, false);
159 // Horizontal fling to lower-right.
161 assertWaitForScroll(false, false);
163 // Vertical fling to upper-right.
165 assertWaitForScroll(false, true);
167 // Horizontal fling to top-left.
169 assertWaitForScroll(true, true);
171 // Diagonal fling to bottom-right.
173 assertWaitForScroll(false, false);
178 public void testScroll() throws Throwable {
179 // Vertical scroll to lower-left.
181 assertWaitForScroll(true, false);
183 // Horizontal scroll to lower-right.
184 scrollTo(2500, 2500);
185 assertWaitForScroll(false, false);
187 // Vertical scroll to upper-right.
189 assertWaitForScroll(false, true);
191 // Horizontal scroll to top-left.
193 assertWaitForScroll(true, true);
195 // Diagonal scroll to bottom-right.
196 scrollTo(2500, 2500);
197 assertWaitForScroll(false, false);
202 * To ensure the device properly responds to bounds-exceeding scrolls, e.g., overscroll
203 * effects are properly initialized.
207 public void testOverScroll() throws Throwable {
208 // Overscroll lower-left.
209 scrollTo(-10000, 10000);
210 assertWaitForScroll(true, false);
212 // Overscroll lower-right.
213 scrollTo(10000, 10000);
214 assertWaitForScroll(false, false);
216 // Overscroll upper-right.
217 scrollTo(10000, -10000);
218 assertWaitForScroll(false, true);
220 // Overscroll top-left.
221 scrollTo(-10000, -10000);
222 assertWaitForScroll(true, true);
224 // Diagonal overscroll lower-right.
225 scrollTo(10000, 10000);
226 assertWaitForScroll(false, false);
230 * To ensure the AccessibilityEvent notifications (Eg:TYPE_VIEW_SCROLLED) are being sent
231 * properly on scrolling a page.
235 public void testOnScrollChanged() throws Throwable {
236 final int scrollToX = 2500;
237 final int scrollToY = 2500;
238 final TestInternalAccessDelegate containerViewInternals = new TestInternalAccessDelegate();
239 runTestOnUiThread(new Runnable() {
242 getContentViewCore().setContainerViewInternals(containerViewInternals);
245 scrollTo(scrollToX, scrollToY);
246 assertWaitForScroll(false, false);
247 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
249 public boolean isSatisfied() {
250 return containerViewInternals.isScrollChanged();