blob: 1122cd8fc34173733ace1f20a345076d012df63a [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.test;
18
Charles Chen49f329c2020-02-13 16:41:32 +080019import static android.view.WindowInsets.Type.displayCutout;
20import static android.view.WindowInsets.Type.navigationBars;
21
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.app.Activity;
23import android.app.Instrumentation;
Charles Chen49f329c2020-02-13 16:41:32 +080024import android.graphics.Insets;
25import android.graphics.Rect;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.SystemClock;
Charles Chen49f329c2020-02-13 16:41:32 +080027import android.util.Size;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.view.Gravity;
29import android.view.MotionEvent;
30import android.view.View;
31import android.view.ViewConfiguration;
32import android.view.ViewGroup;
Charles Chen49f329c2020-02-13 16:41:32 +080033import android.view.WindowInsets;
34import android.view.WindowManager;
35import android.view.WindowMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37/**
38 * Reusable methods for generating touch events. These methods can be used with
39 * InstrumentationTestCase or ActivityInstrumentationTestCase2 to simulate user interaction with
40 * the application through a touch screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -080041 *
42 * @deprecated Use
43 * <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso UI testing
44 * framework</a> instead. New tests should be written using the
45 * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 */
Stephan Linznerb51617f2016-01-27 18:09:50 -080047@Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048public class TouchUtils {
Stephan Linznerb51617f2016-01-27 18:09:50 -080049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 /**
51 * Simulate touching in the center of the screen and dragging one quarter of the way down
52 * @param test The test case that is being run
53 *
54 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
55 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
56 * configuring the Activity under test
57 */
58 @Deprecated
59 public static void dragQuarterScreenDown(ActivityInstrumentationTestCase test) {
60 dragQuarterScreenDown(test, test.getActivity());
61 }
Stephan Linznerb51617f2016-01-27 18:09:50 -080062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 /**
64 * Simulate touching in the center of the screen and dragging one quarter of the way down
65 * @param test The test case that is being run
66 * @param activity The activity that is in the foreground of the test case
67 */
68 public static void dragQuarterScreenDown(InstrumentationTestCase test, Activity activity) {
Charles Chen49f329c2020-02-13 16:41:32 +080069 WindowManager wm = activity.getWindowManager();
70 final Size size = getSizeExcludingNavigationBarAndCutout(wm.getCurrentWindowMetrics());
Stephan Linznerb51617f2016-01-27 18:09:50 -080071
Charles Chen49f329c2020-02-13 16:41:32 +080072 final float x = size.getWidth() / 2.0f;
73 final float fromY = size.getHeight() * 0.5f;
74 final float toY = size.getHeight() * 0.75f;
Stephan Linznerb51617f2016-01-27 18:09:50 -080075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 drag(test, x, x, fromY, toY, 4);
77 }
Stephan Linznerb51617f2016-01-27 18:09:50 -080078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 /**
80 * Simulate touching in the center of the screen and dragging one quarter of the way up
81 * @param test The test case that is being run
82 *
83 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
84 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
85 * configuring the Activity under test
86 */
87 @Deprecated
88 public static void dragQuarterScreenUp(ActivityInstrumentationTestCase test) {
89 dragQuarterScreenUp(test, test.getActivity());
90 }
Stephan Linznerb51617f2016-01-27 18:09:50 -080091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 /**
93 * Simulate touching in the center of the screen and dragging one quarter of the way up
94 * @param test The test case that is being run
95 * @param activity The activity that is in the foreground of the test case
96 */
97 public static void dragQuarterScreenUp(InstrumentationTestCase test, Activity activity) {
Charles Chen49f329c2020-02-13 16:41:32 +080098 WindowManager wm = activity.getWindowManager();
99 final Size size = getSizeExcludingNavigationBarAndCutout(wm.getCurrentWindowMetrics());
Stephan Linznerb51617f2016-01-27 18:09:50 -0800100
Charles Chen49f329c2020-02-13 16:41:32 +0800101 final float x = size.getWidth() / 2.0f;
102 final float fromY = size.getHeight() * 0.5f;
103 final float toY = size.getHeight() * 0.25f;
Stephan Linznerb51617f2016-01-27 18:09:50 -0800104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 drag(test, x, x, fromY, toY, 4);
106 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800107
Charles Chen49f329c2020-02-13 16:41:32 +0800108 private static Size getSizeExcludingNavigationBarAndCutout(WindowMetrics windowMetrics) {
109 WindowInsets windowInsets = windowMetrics.getWindowInsets();
110 final Insets insetsWithCutout = windowInsets
111 .getInsetsIgnoringVisibility(navigationBars() | displayCutout());
112 final int insetsWidth = insetsWithCutout.left + insetsWithCutout.right;
113 final int insetsHeight = insetsWithCutout.top + insetsWithCutout.bottom;
114
115 Rect bounds = windowMetrics.getBounds();
116 return new Size(bounds.width() - insetsWidth, bounds.height() - insetsHeight);
117 }
118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 /**
120 * Scroll a ViewGroup to the bottom by repeatedly calling
121 * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
Stephan Linznerb51617f2016-01-27 18:09:50 -0800122 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 * @param test The test case that is being run
124 * @param v The ViewGroup that should be dragged
125 *
126 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
127 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
128 * configuring the Activity under test
129 */
130 @Deprecated
131 public static void scrollToBottom(ActivityInstrumentationTestCase test, ViewGroup v) {
132 scrollToBottom(test, test.getActivity(), v);
133 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 /**
136 * Scroll a ViewGroup to the bottom by repeatedly calling
137 * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
Stephan Linznerb51617f2016-01-27 18:09:50 -0800138 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 * @param test The test case that is being run
140 * @param activity The activity that is in the foreground of the test case
141 * @param v The ViewGroup that should be dragged
142 */
143 public static void scrollToBottom(InstrumentationTestCase test, Activity activity,
144 ViewGroup v) {
Yigit Boyarde8d7892014-09-22 15:22:45 -0700145 ViewStateSnapshot prev;
146 ViewStateSnapshot next = new ViewStateSnapshot(v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 do {
Yigit Boyarde8d7892014-09-22 15:22:45 -0700148 prev = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 TouchUtils.dragQuarterScreenUp(test, activity);
Yigit Boyarde8d7892014-09-22 15:22:45 -0700150 next = new ViewStateSnapshot(v);
151 } while (!prev.equals(next));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 }
153
154 /**
155 * Scroll a ViewGroup to the top by repeatedly calling
156 * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
Stephan Linznerb51617f2016-01-27 18:09:50 -0800157 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 * @param test The test case that is being run
159 * @param v The ViewGroup that should be dragged
160 *
161 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
162 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
163 * configuring the Activity under test
164 */
165 @Deprecated
166 public static void scrollToTop(ActivityInstrumentationTestCase test, ViewGroup v) {
167 scrollToTop(test, test.getActivity(), v);
168 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 /**
171 * Scroll a ViewGroup to the top by repeatedly calling
172 * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
Stephan Linznerb51617f2016-01-27 18:09:50 -0800173 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 * @param test The test case that is being run
175 * @param activity The activity that is in the foreground of the test case
176 * @param v The ViewGroup that should be dragged
177 */
178 public static void scrollToTop(InstrumentationTestCase test, Activity activity, ViewGroup v) {
Yigit Boyarde8d7892014-09-22 15:22:45 -0700179 ViewStateSnapshot prev;
180 ViewStateSnapshot next = new ViewStateSnapshot(v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 do {
Yigit Boyarde8d7892014-09-22 15:22:45 -0700182 prev = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 TouchUtils.dragQuarterScreenDown(test, activity);
Yigit Boyarde8d7892014-09-22 15:22:45 -0700184 next = new ViewStateSnapshot(v);
185 } while (!prev.equals(next));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 /**
189 * Simulate touching the center of a view and dragging to the bottom of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800190 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 * @param test The test case that is being run
192 * @param v The view that should be dragged
193 *
194 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
195 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
196 * configuring the Activity under test
197 */
198 @Deprecated
199 public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v) {
200 dragViewToBottom(test, test.getActivity(), v, 4);
201 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 /**
204 * Simulate touching the center of a view and dragging to the bottom of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800205 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 * @param test The test case that is being run
207 * @param activity The activity that is in the foreground of the test case
208 * @param v The view that should be dragged
209 */
210 public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v) {
211 dragViewToBottom(test, activity, v, 4);
212 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 /**
215 * Simulate touching the center of a view and dragging to the bottom of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800216 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 * @param test The test case that is being run
218 * @param v The view that should be dragged
219 * @param stepCount How many move steps to include in the drag
220 *
221 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
222 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
223 * configuring the Activity under test
224 */
225 @Deprecated
226 public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v,
227 int stepCount) {
228 dragViewToBottom(test, test.getActivity(), v, stepCount);
229 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 /**
232 * Simulate touching the center of a view and dragging to the bottom of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800233 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 * @param test The test case that is being run
235 * @param activity The activity that is in the foreground of the test case
236 * @param v The view that should be dragged
237 * @param stepCount How many move steps to include in the drag
238 */
239 public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v,
240 int stepCount) {
Charles Chen49f329c2020-02-13 16:41:32 +0800241 WindowManager wm = activity.getWindowManager();
242 final int screenHeight = getSizeExcludingNavigationBarAndCutout(
243 wm.getCurrentWindowMetrics()).getHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244
245 int[] xy = new int[2];
246 v.getLocationOnScreen(xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 final int viewWidth = v.getWidth();
249 final int viewHeight = v.getHeight();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 final float x = xy[0] + (viewWidth / 2.0f);
252 float fromY = xy[1] + (viewHeight / 2.0f);
253 float toY = screenHeight - 1;
Stephan Linznerb51617f2016-01-27 18:09:50 -0800254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 drag(test, x, x, fromY, toY, stepCount);
256 }
257
258 /**
259 * Simulate touching the center of a view and releasing quickly (before the tap timeout).
Stephan Linznerb51617f2016-01-27 18:09:50 -0800260 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 * @param test The test case that is being run
262 * @param v The view that should be clicked
263 */
264 public static void tapView(InstrumentationTestCase test, View v) {
265 int[] xy = new int[2];
266 v.getLocationOnScreen(xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 final int viewWidth = v.getWidth();
269 final int viewHeight = v.getHeight();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 final float x = xy[0] + (viewWidth / 2.0f);
272 float y = xy[1] + (viewHeight / 2.0f);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 Instrumentation inst = test.getInstrumentation();
275
276 long downTime = SystemClock.uptimeMillis();
277 long eventTime = SystemClock.uptimeMillis();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
280 MotionEvent.ACTION_DOWN, x, y, 0);
281 inst.sendPointerSync(event);
282 inst.waitForIdleSync();
283
284 eventTime = SystemClock.uptimeMillis();
285 final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
286 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
287 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
288 inst.sendPointerSync(event);
289 inst.waitForIdleSync();
290
291 eventTime = SystemClock.uptimeMillis();
292 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
293 inst.sendPointerSync(event);
294 inst.waitForIdleSync();
295 }
296
297 /**
298 * Simulate touching the center of a view and cancelling (so no onClick should
299 * fire, etc).
300 *
301 * @param test The test case that is being run
302 * @param v The view that should be clicked
303 */
304 public static void touchAndCancelView(InstrumentationTestCase test, View v) {
305 int[] xy = new int[2];
306 v.getLocationOnScreen(xy);
307
308 final int viewWidth = v.getWidth();
309 final int viewHeight = v.getHeight();
310
311 final float x = xy[0] + (viewWidth / 2.0f);
312 float y = xy[1] + (viewHeight / 2.0f);
313
314 Instrumentation inst = test.getInstrumentation();
315
316 long downTime = SystemClock.uptimeMillis();
317 long eventTime = SystemClock.uptimeMillis();
318
319 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
320 MotionEvent.ACTION_DOWN, x, y, 0);
321 inst.sendPointerSync(event);
322 inst.waitForIdleSync();
323
324 eventTime = SystemClock.uptimeMillis();
325 final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
326 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL,
327 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
328 inst.sendPointerSync(event);
329 inst.waitForIdleSync();
330
331 }
332
333 /**
334 * Simulate touching the center of a view and releasing.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800335 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 * @param test The test case that is being run
337 * @param v The view that should be clicked
338 */
339 public static void clickView(InstrumentationTestCase test, View v) {
340 int[] xy = new int[2];
341 v.getLocationOnScreen(xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 final int viewWidth = v.getWidth();
344 final int viewHeight = v.getHeight();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 final float x = xy[0] + (viewWidth / 2.0f);
347 float y = xy[1] + (viewHeight / 2.0f);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 Instrumentation inst = test.getInstrumentation();
350
351 long downTime = SystemClock.uptimeMillis();
352 long eventTime = SystemClock.uptimeMillis();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
355 MotionEvent.ACTION_DOWN, x, y, 0);
356 inst.sendPointerSync(event);
357 inst.waitForIdleSync();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359
360 eventTime = SystemClock.uptimeMillis();
361 final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
362 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
363 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
364 inst.sendPointerSync(event);
365 inst.waitForIdleSync();
366
367 eventTime = SystemClock.uptimeMillis();
368 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
369 inst.sendPointerSync(event);
370 inst.waitForIdleSync();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 try {
373 Thread.sleep(1000);
374 } catch (InterruptedException e) {
375 e.printStackTrace();
376 }
377 }
378
379 /**
380 * Simulate touching the center of a view, holding until it is a long press, and then releasing.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800381 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 * @param test The test case that is being run
383 * @param v The view that should be clicked
384 *
385 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
386 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
387 * configuring the Activity under test
388 */
389 @Deprecated
390 public static void longClickView(ActivityInstrumentationTestCase test, View v) {
391 longClickView((InstrumentationTestCase) test, v);
392 }
393
394 /**
395 * Simulate touching the center of a view, holding until it is a long press, and then releasing.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800396 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 * @param test The test case that is being run
398 * @param v The view that should be clicked
399 */
400 public static void longClickView(InstrumentationTestCase test, View v) {
401 int[] xy = new int[2];
402 v.getLocationOnScreen(xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 final int viewWidth = v.getWidth();
405 final int viewHeight = v.getHeight();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 final float x = xy[0] + (viewWidth / 2.0f);
408 float y = xy[1] + (viewHeight / 2.0f);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 Instrumentation inst = test.getInstrumentation();
411
412 long downTime = SystemClock.uptimeMillis();
413 long eventTime = SystemClock.uptimeMillis();
414
415 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
416 MotionEvent.ACTION_DOWN, x, y, 0);
417 inst.sendPointerSync(event);
418 inst.waitForIdleSync();
419
420 eventTime = SystemClock.uptimeMillis();
421 final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
422 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
423 x + touchSlop / 2, y + touchSlop / 2, 0);
424 inst.sendPointerSync(event);
425 inst.waitForIdleSync();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 try {
428 Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f));
429 } catch (InterruptedException e) {
430 e.printStackTrace();
431 }
432
433 eventTime = SystemClock.uptimeMillis();
434 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
435 inst.sendPointerSync(event);
436 inst.waitForIdleSync();
437 }
438
439 /**
440 * Simulate touching the center of a view and dragging to the top of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800441 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 * @param test The test case that is being run
443 * @param v The view that should be dragged
444 *
445 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
446 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
447 * configuring the Activity under test
448 */
449 @Deprecated
450 public static void dragViewToTop(ActivityInstrumentationTestCase test, View v) {
451 dragViewToTop((InstrumentationTestCase) test, v, 4);
452 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 /**
455 * Simulate touching the center of a view and dragging to the top of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800456 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 * @param test The test case that is being run
458 * @param v The view that should be dragged
459 * @param stepCount How many move steps to include in the drag
460 *
461 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
462 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
463 * configuring the Activity under test
464 */
465 @Deprecated
466 public static void dragViewToTop(ActivityInstrumentationTestCase test, View v, int stepCount) {
467 dragViewToTop((InstrumentationTestCase) test, v, stepCount);
468 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 /**
471 * Simulate touching the center of a view and dragging to the top of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800472 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 * @param test The test case that is being run
474 * @param v The view that should be dragged
475 */
476 public static void dragViewToTop(InstrumentationTestCase test, View v) {
477 dragViewToTop(test, v, 4);
478 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 /**
481 * Simulate touching the center of a view and dragging to the top of the screen.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800482 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 * @param test The test case that is being run
484 * @param v The view that should be dragged
485 * @param stepCount How many move steps to include in the drag
486 */
487 public static void dragViewToTop(InstrumentationTestCase test, View v, int stepCount) {
488 int[] xy = new int[2];
489 v.getLocationOnScreen(xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 final int viewWidth = v.getWidth();
492 final int viewHeight = v.getHeight();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 final float x = xy[0] + (viewWidth / 2.0f);
495 float fromY = xy[1] + (viewHeight / 2.0f);
496 float toY = 0;
Stephan Linznerb51617f2016-01-27 18:09:50 -0800497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 drag(test, x, x, fromY, toY, stepCount);
499 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 /**
502 * Get the location of a view. Use the gravity param to specify which part of the view to
503 * return.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800504 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 * @param v View to find
506 * @param gravity A combination of (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL,
507 * RIGHT)
508 * @param xy Result
509 */
510 private static void getStartLocation(View v, int gravity, int[] xy) {
511 v.getLocationOnScreen(xy);
512
513 final int viewWidth = v.getWidth();
514 final int viewHeight = v.getHeight();
Stephan Linznerb51617f2016-01-27 18:09:50 -0800515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
517 case Gravity.TOP:
518 break;
519 case Gravity.CENTER_VERTICAL:
520 xy[1] += viewHeight / 2;
521 break;
522 case Gravity.BOTTOM:
523 xy[1] += viewHeight - 1;
524 break;
525 default:
526 // Same as top -- do nothing
527 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
530 case Gravity.LEFT:
531 break;
532 case Gravity.CENTER_HORIZONTAL:
533 xy[0] += viewWidth / 2;
534 break;
535 case Gravity.RIGHT:
536 xy[0] += viewWidth - 1;
537 break;
538 default:
539 // Same as left -- do nothing
540 }
541 }
542
543 /**
544 * Simulate touching a view and dragging it by the specified amount.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800545 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 * @param test The test case that is being run
547 * @param v The view that should be dragged
548 * @param gravity Which part of the view to use for the initial down event. A combination of
549 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
550 * @param deltaX Amount to drag horizontally in pixels
551 * @param deltaY Amount to drag vertically in pixels
Stephan Linznerb51617f2016-01-27 18:09:50 -0800552 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 * @return distance in pixels covered by the drag
554 *
555 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
556 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
557 * configuring the Activity under test
558 */
559 @Deprecated
560 public static int dragViewBy(ActivityInstrumentationTestCase test, View v, int gravity,
561 int deltaX, int deltaY) {
562 return dragViewBy((InstrumentationTestCase) test, v, gravity, deltaX, deltaY);
563 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 /**
566 * Simulate touching a view and dragging it by the specified amount.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800567 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 * @param test The test case that is being run
569 * @param v The view that should be dragged
570 * @param gravity Which part of the view to use for the initial down event. A combination of
571 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
572 * @param deltaX Amount to drag horizontally in pixels
573 * @param deltaY Amount to drag vertically in pixels
Stephan Linznerb51617f2016-01-27 18:09:50 -0800574 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 * @return distance in pixels covered by the drag
576 *
577 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
578 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
579 * configuring the Activity under test
580 */
Jean-Baptiste Queru9db3d072009-11-12 18:45:53 -0800581 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 public static int dragViewBy(InstrumentationTestCase test, View v, int gravity, int deltaX,
583 int deltaY) {
584 int[] xy = new int[2];
Stephan Linznerb51617f2016-01-27 18:09:50 -0800585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 getStartLocation(v, gravity, xy);
587
588 final int fromX = xy[0];
589 final int fromY = xy[1];
Stephan Linznerb51617f2016-01-27 18:09:50 -0800590
Neil Fuller33253a42014-10-01 11:55:10 +0100591 int distance = (int) Math.hypot(deltaX, deltaY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592
593 drag(test, fromX, fromX + deltaX, fromY, fromY + deltaY, distance);
594
595 return distance;
596 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 /**
599 * Simulate touching a view and dragging it to a specified location.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800600 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 * @param test The test case that is being run
602 * @param v The view that should be dragged
603 * @param gravity Which part of the view to use for the initial down event. A combination of
604 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
605 * @param toX Final location of the view after dragging
606 * @param toY Final location of the view after dragging
Stephan Linznerb51617f2016-01-27 18:09:50 -0800607 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 * @return distance in pixels covered by the drag
609 *
610 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
611 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
612 * configuring the Activity under test
613 */
614 @Deprecated
615 public static int dragViewTo(ActivityInstrumentationTestCase test, View v, int gravity, int toX,
616 int toY) {
617 return dragViewTo((InstrumentationTestCase) test, v, gravity, toX, toY);
618 }
619
620 /**
621 * Simulate touching a view and dragging it to a specified location.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800622 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 * @param test The test case that is being run
624 * @param v The view that should be dragged
625 * @param gravity Which part of the view to use for the initial down event. A combination of
626 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
627 * @param toX Final location of the view after dragging
628 * @param toY Final location of the view after dragging
Stephan Linznerb51617f2016-01-27 18:09:50 -0800629 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 * @return distance in pixels covered by the drag
631 */
632 public static int dragViewTo(InstrumentationTestCase test, View v, int gravity, int toX,
633 int toY) {
634 int[] xy = new int[2];
635
636 getStartLocation(v, gravity, xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 final int fromX = xy[0];
639 final int fromY = xy[1];
Stephan Linznerb51617f2016-01-27 18:09:50 -0800640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 int deltaX = fromX - toX;
642 int deltaY = fromY - toY;
Stephan Linznerb51617f2016-01-27 18:09:50 -0800643
Neil Fuller33253a42014-10-01 11:55:10 +0100644 int distance = (int)Math.hypot(deltaX, deltaY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 drag(test, fromX, toX, fromY, toY, distance);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 return distance;
648 }
649
650 /**
651 * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800652 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 * @param test The test case that is being run
654 * @param v The view that should be dragged
655 * @param gravity Which part of the view to use for the initial down event. A combination of
656 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
657 * @param toX Final location of the view after dragging
Stephan Linznerb51617f2016-01-27 18:09:50 -0800658 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 * @return distance in pixels covered by the drag
660 *
661 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
662 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
663 * configuring the Activity under test
664 */
665 @Deprecated
666 public static int dragViewToX(ActivityInstrumentationTestCase test, View v, int gravity,
667 int toX) {
668 return dragViewToX((InstrumentationTestCase) test, v, gravity, toX);
669 }
670
671 /**
672 * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800673 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 * @param test The test case that is being run
675 * @param v The view that should be dragged
676 * @param gravity Which part of the view to use for the initial down event. A combination of
677 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
678 * @param toX Final location of the view after dragging
Stephan Linznerb51617f2016-01-27 18:09:50 -0800679 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 * @return distance in pixels covered by the drag
681 */
682 public static int dragViewToX(InstrumentationTestCase test, View v, int gravity, int toX) {
683 int[] xy = new int[2];
684
685 getStartLocation(v, gravity, xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 final int fromX = xy[0];
688 final int fromY = xy[1];
Stephan Linznerb51617f2016-01-27 18:09:50 -0800689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 int deltaX = fromX - toX;
691
692 drag(test, fromX, toX, fromY, fromY, deltaX);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 return deltaX;
695 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697 /**
698 * Simulate touching a view and dragging it to a specified location. Only moves vertically.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800699 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 * @param test The test case that is being run
701 * @param v The view that should be dragged
702 * @param gravity Which part of the view to use for the initial down event. A combination of
703 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
704 * @param toY Final location of the view after dragging
Stephan Linznerb51617f2016-01-27 18:09:50 -0800705 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706 * @return distance in pixels covered by the drag
707 *
708 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
709 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
710 * configuring the Activity under test
711 */
712 @Deprecated
713 public static int dragViewToY(ActivityInstrumentationTestCase test, View v, int gravity,
714 int toY) {
715 return dragViewToY((InstrumentationTestCase) test, v, gravity, toY);
716 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 /**
719 * Simulate touching a view and dragging it to a specified location. Only moves vertically.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800720 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 * @param test The test case that is being run
722 * @param v The view that should be dragged
723 * @param gravity Which part of the view to use for the initial down event. A combination of
724 * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
725 * @param toY Final location of the view after dragging
Stephan Linznerb51617f2016-01-27 18:09:50 -0800726 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 * @return distance in pixels covered by the drag
728 */
729 public static int dragViewToY(InstrumentationTestCase test, View v, int gravity, int toY) {
730 int[] xy = new int[2];
731
732 getStartLocation(v, gravity, xy);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 final int fromX = xy[0];
735 final int fromY = xy[1];
Stephan Linznerb51617f2016-01-27 18:09:50 -0800736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 int deltaY = fromY - toY;
738
739 drag(test, fromX, fromX, fromY, toY, deltaY);
Stephan Linznerb51617f2016-01-27 18:09:50 -0800740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 return deltaY;
742 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744
745 /**
746 * Simulate touching a specific location and dragging to a new location.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800747 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 * @param test The test case that is being run
749 * @param fromX X coordinate of the initial touch, in screen coordinates
750 * @param toX Xcoordinate of the drag destination, in screen coordinates
751 * @param fromY X coordinate of the initial touch, in screen coordinates
752 * @param toY Y coordinate of the drag destination, in screen coordinates
753 * @param stepCount How many move steps to include in the drag
754 *
755 * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
756 * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
757 * configuring the Activity under test
758 */
759 @Deprecated
760 public static void drag(ActivityInstrumentationTestCase test, float fromX, float toX,
761 float fromY, float toY, int stepCount) {
762 drag((InstrumentationTestCase) test, fromX, toX, fromY, toY, stepCount);
763 }
Stephan Linznerb51617f2016-01-27 18:09:50 -0800764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 /**
766 * Simulate touching a specific location and dragging to a new location.
Stephan Linznerb51617f2016-01-27 18:09:50 -0800767 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 * @param test The test case that is being run
769 * @param fromX X coordinate of the initial touch, in screen coordinates
770 * @param toX Xcoordinate of the drag destination, in screen coordinates
771 * @param fromY X coordinate of the initial touch, in screen coordinates
772 * @param toY Y coordinate of the drag destination, in screen coordinates
773 * @param stepCount How many move steps to include in the drag
774 */
775 public static void drag(InstrumentationTestCase test, float fromX, float toX, float fromY,
776 float toY, int stepCount) {
777 Instrumentation inst = test.getInstrumentation();
778
779 long downTime = SystemClock.uptimeMillis();
780 long eventTime = SystemClock.uptimeMillis();
781
782 float y = fromY;
783 float x = fromX;
Stephan Linznerb51617f2016-01-27 18:09:50 -0800784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 float yStep = (toY - fromY) / stepCount;
786 float xStep = (toX - fromX) / stepCount;
787
788 MotionEvent event = MotionEvent.obtain(downTime, eventTime,
Marc Capdevielle8621cfa2010-02-05 19:28:23 +0100789 MotionEvent.ACTION_DOWN, x, y, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 inst.sendPointerSync(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 for (int i = 0; i < stepCount; ++i) {
792 y += yStep;
793 x += xStep;
794 eventTime = SystemClock.uptimeMillis();
795 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
796 inst.sendPointerSync(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 }
798
799 eventTime = SystemClock.uptimeMillis();
Marc Capdevielle8621cfa2010-02-05 19:28:23 +0100800 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 inst.sendPointerSync(event);
802 inst.waitForIdleSync();
803 }
Yigit Boyarde8d7892014-09-22 15:22:45 -0700804
805 private static class ViewStateSnapshot {
806 final View mFirst;
807 final View mLast;
808 final int mFirstTop;
809 final int mLastBottom;
810 final int mChildCount;
811 private ViewStateSnapshot(ViewGroup viewGroup) {
812 mChildCount = viewGroup.getChildCount();
813 if (mChildCount == 0) {
814 mFirst = mLast = null;
815 mFirstTop = mLastBottom = Integer.MIN_VALUE;
816 } else {
817 mFirst = viewGroup.getChildAt(0);
818 mLast = viewGroup.getChildAt(mChildCount - 1);
819 mFirstTop = mFirst.getTop();
820 mLastBottom = mLast.getBottom();
821 }
822 }
823
824 @Override
825 public boolean equals(Object o) {
826 if (this == o) {
827 return true;
828 }
829 if (o == null || getClass() != o.getClass()) {
830 return false;
831 }
832
833 final ViewStateSnapshot that = (ViewStateSnapshot) o;
834 return mFirstTop == that.mFirstTop &&
835 mLastBottom == that.mLastBottom &&
836 mFirst == that.mFirst &&
837 mLast == that.mLast &&
838 mChildCount == that.mChildCount;
839 }
840
841 @Override
842 public int hashCode() {
843 int result = mFirst != null ? mFirst.hashCode() : 0;
844 result = 31 * result + (mLast != null ? mLast.hashCode() : 0);
845 result = 31 * result + mFirstTop;
846 result = 31 * result + mLastBottom;
847 result = 31 * result + mChildCount;
848 return result;
849 }
850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851}