1 // Copyright (c) 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.test.util;
7 import android.os.SystemClock;
8 import android.view.MotionEvent;
9 import android.view.View;
10 import android.view.ViewConfiguration;
11 import android.test.ActivityInstrumentationTestCase2;
14 * Touch-related functionality reused across test cases.
16 public class TouchCommon {
17 private ActivityInstrumentationTestCase2 mActivityTestCase;
19 // TODO(leandrogracia): This method should receive and use an activity
20 // instead of the ActivityInstrumentationTestCase2. However this is causing
21 // problems downstream. Any fix for this should be landed downstream first.
22 public TouchCommon(ActivityInstrumentationTestCase2 activityTestCase) {
23 mActivityTestCase = activityTestCase;
27 * Starts (synchronously) a drag motion. Normally followed by dragTo() and dragEnd().
31 * @param downTime (in ms)
34 public void dragStart(float x, float y, long downTime) {
35 MotionEvent event = MotionEvent.obtain(downTime, downTime,
36 MotionEvent.ACTION_DOWN, x, y, 0);
37 dispatchTouchEvent(event);
41 * Drags / moves (synchronously) to the specified coordinates. Normally preceeded by
42 * dragStart() and followed by dragEnd()
49 * @param downTime (in ms)
52 public void dragTo(float fromX, float toX, float fromY,
53 float toY, int stepCount, long downTime) {
56 float yStep = (toY - fromY) / stepCount;
57 float xStep = (toX - fromX) / stepCount;
58 for (int i = 0; i < stepCount; ++i) {
61 long eventTime = SystemClock.uptimeMillis();
62 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
63 MotionEvent.ACTION_MOVE, x, y, 0);
64 dispatchTouchEvent(event);
69 * Finishes (synchronously) a drag / move at the specified coordinate.
70 * Normally preceeded by dragStart() and dragTo().
74 * @param downTime (in ms)
77 public void dragEnd(float x, float y, long downTime) {
78 long eventTime = SystemClock.uptimeMillis();
79 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
80 MotionEvent.ACTION_UP, x, y, 0);
81 dispatchTouchEvent(event);
85 * Sends (synchronously) a single click to an absolute screen coordinates.
87 * @param x screen absolute
88 * @param y screen absolute
91 public void singleClick(float x, float y) {
93 long downTime = SystemClock.uptimeMillis();
94 long eventTime = SystemClock.uptimeMillis();
96 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
97 MotionEvent.ACTION_DOWN, x, y, 0);
98 dispatchTouchEvent(event);
100 eventTime = SystemClock.uptimeMillis();
101 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP,
103 dispatchTouchEvent(event);
107 * Sends (synchronously) a single click to the View at the specified coordinates.
109 * @param v The view to be clicked.
110 * @param x Relative x location to v
111 * @param y Relative y location to v
113 public void singleClickView(View v, int x, int y) {
114 int location[] = getAbsoluteLocationFromRelative(v, x, y);
115 int absoluteX = location[0];
116 int absoluteY = location[1];
117 singleClick(absoluteX, absoluteY);
121 * Sends (synchronously) a single click to the center of the View.
123 public void singleClickView(View v) {
124 singleClickView(v, v.getWidth() / 2, v.getHeight() / 2);
128 * Sends (synchronously) a single click on the specified relative coordinates inside
131 * @param view The view to be clicked.
132 * @param x screen absolute
133 * @param y screen absolute
136 public void singleClickViewRelative(View view, int x, int y) {
137 long downTime = SystemClock.uptimeMillis();
138 long eventTime = SystemClock.uptimeMillis();
140 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
141 MotionEvent.ACTION_DOWN, x, y, 0);
142 dispatchTouchEvent(view, event);
144 eventTime = SystemClock.uptimeMillis();
145 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP,
147 dispatchTouchEvent(view, event);
151 * Sends (synchronously) a long press to an absolute screen coordinates.
153 * @param x screen absolute
154 * @param y screen absolute
157 public void longPress(float x, float y) {
159 long downTime = SystemClock.uptimeMillis();
160 long eventTime = SystemClock.uptimeMillis();
162 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
163 MotionEvent.ACTION_DOWN, x, y, 0);
164 dispatchTouchEvent(event);
166 int longPressTimeout = ViewConfiguration.get(
167 mActivityTestCase.getActivity()).getLongPressTimeout();
169 // Long press is flaky with just longPressTimeout. Doubling the time to be safe.
170 SystemClock.sleep(longPressTimeout * 2);
172 eventTime = SystemClock.uptimeMillis();
173 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP,
175 dispatchTouchEvent(event);
179 * Sends (synchronously) a long press to the View at the specified coordinates.
181 * @param v The view to be clicked.
182 * @param x Relative x location to v
183 * @param y Relative y location to v
185 public void longPressView(View v, int x, int y) {
186 int location[] = getAbsoluteLocationFromRelative(v, x, y);
187 int absoluteX = location[0];
188 int absoluteY = location[1];
189 longPress(absoluteX, absoluteY);
193 * Send a MotionEvent to the root view of the activity.
196 private void dispatchTouchEvent(final MotionEvent event) {
198 mActivityTestCase.getActivity().findViewById(android.R.id.content).getRootView();
199 dispatchTouchEvent(view, event);
203 * Send a MotionEvent to the specified view instead of the root view.
204 * For example AutofillPopup window that is above the root view.
205 * @param view The view that should receive the event.
206 * @param event The view to be dispatched.
208 private void dispatchTouchEvent(final View view, final MotionEvent event) {
210 mActivityTestCase.runTestOnUiThread(new Runnable() {
213 view.dispatchTouchEvent(event);
216 } catch(Throwable e) {
217 throw new RuntimeException("Dispatching touch event failed", e);
222 * Returns the absolute location in screen coordinates from location relative
224 * @param v The view the coordinates are relative to.
225 * @param x Relative x location.
226 * @param y Relative y location.
227 * @return absolute x and y location in an array.
229 private static int[] getAbsoluteLocationFromRelative(View v, int x, int y) {
230 int location[] = new int[2];
231 v.getLocationOnScreen(location);