• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.test;
18 
19 import android.app.Activity;
20 import android.app.Instrumentation;
21 import android.graphics.Point;
22 import android.os.SystemClock;
23 import android.view.Display;
24 import android.view.Gravity;
25 import android.view.MotionEvent;
26 import android.view.View;
27 import android.view.ViewConfiguration;
28 import android.view.ViewGroup;
29 
30 /**
31  * Reusable methods for generating touch events. These methods can be used with
32  * InstrumentationTestCase or ActivityInstrumentationTestCase2 to simulate user interaction with
33  * the application through a touch screen.
34  */
35 public class TouchUtils {
36 
37     /**
38      * Simulate touching in the center of the screen and dragging one quarter of the way down
39      * @param test The test case that is being run
40      *
41      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
42      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
43      * configuring the Activity under test
44      */
45     @Deprecated
dragQuarterScreenDown(ActivityInstrumentationTestCase test)46     public static void dragQuarterScreenDown(ActivityInstrumentationTestCase test) {
47         dragQuarterScreenDown(test, test.getActivity());
48     }
49 
50     /**
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      * @param activity The activity that is in the foreground of the test case
54      */
dragQuarterScreenDown(InstrumentationTestCase test, Activity activity)55     public static void dragQuarterScreenDown(InstrumentationTestCase test, Activity activity) {
56         Display display = activity.getWindowManager().getDefaultDisplay();
57         final Point size = new Point();
58         display.getSize(size);
59 
60         final float x = size.x / 2.0f;
61         final float fromY = size.y * 0.5f;
62         final float toY = size.y * 0.75f;
63 
64         drag(test, x, x, fromY, toY, 4);
65     }
66 
67     /**
68      * Simulate touching in the center of the screen and dragging one quarter of the way up
69      * @param test The test case that is being run
70      *
71      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
72      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
73      * configuring the Activity under test
74      */
75     @Deprecated
dragQuarterScreenUp(ActivityInstrumentationTestCase test)76     public static void dragQuarterScreenUp(ActivityInstrumentationTestCase test) {
77         dragQuarterScreenUp(test, test.getActivity());
78     }
79 
80     /**
81      * Simulate touching in the center of the screen and dragging one quarter of the way up
82      * @param test The test case that is being run
83      * @param activity The activity that is in the foreground of the test case
84      */
dragQuarterScreenUp(InstrumentationTestCase test, Activity activity)85     public static void dragQuarterScreenUp(InstrumentationTestCase test, Activity activity) {
86         Display display = activity.getWindowManager().getDefaultDisplay();
87         final Point size = new Point();
88         display.getSize(size);
89 
90         final float x = size.x / 2.0f;
91         final float fromY = size.y * 0.5f;
92         final float toY = size.y * 0.25f;
93 
94         drag(test, x, x, fromY, toY, 4);
95     }
96 
97     /**
98      * Scroll a ViewGroup to the bottom by repeatedly calling
99      * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
100      *
101      * @param test The test case that is being run
102      * @param v The ViewGroup that should be dragged
103      *
104      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
105      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
106      * configuring the Activity under test
107      */
108     @Deprecated
scrollToBottom(ActivityInstrumentationTestCase test, ViewGroup v)109     public static void scrollToBottom(ActivityInstrumentationTestCase test, ViewGroup v) {
110         scrollToBottom(test, test.getActivity(), v);
111     }
112 
113     /**
114      * Scroll a ViewGroup to the bottom by repeatedly calling
115      * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
116      *
117      * @param test The test case that is being run
118      * @param activity The activity that is in the foreground of the test case
119      * @param v The ViewGroup that should be dragged
120      */
scrollToBottom(InstrumentationTestCase test, Activity activity, ViewGroup v)121     public static void scrollToBottom(InstrumentationTestCase test, Activity activity,
122             ViewGroup v) {
123         View firstChild;
124         int firstId = Integer.MIN_VALUE;
125         int firstTop = Integer.MIN_VALUE;
126         int prevId;
127         int prevTop;
128         do {
129             prevId = firstId;
130             prevTop = firstTop;
131             TouchUtils.dragQuarterScreenUp(test, activity);
132             firstChild = v.getChildAt(0);
133             firstId = firstChild.getId();
134             firstTop = firstChild.getTop();
135         } while ((prevId != firstId) || (prevTop != firstTop));
136     }
137 
138     /**
139      * Scroll a ViewGroup to the top by repeatedly calling
140      * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
141      *
142      * @param test The test case that is being run
143      * @param v The ViewGroup that should be dragged
144      *
145      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
146      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
147      * configuring the Activity under test
148      */
149     @Deprecated
scrollToTop(ActivityInstrumentationTestCase test, ViewGroup v)150     public static void scrollToTop(ActivityInstrumentationTestCase test, ViewGroup v) {
151         scrollToTop(test, test.getActivity(), v);
152     }
153 
154     /**
155      * Scroll a ViewGroup to the top by repeatedly calling
156      * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
157      *
158      * @param test The test case that is being run
159      * @param activity The activity that is in the foreground of the test case
160      * @param v The ViewGroup that should be dragged
161      */
scrollToTop(InstrumentationTestCase test, Activity activity, ViewGroup v)162     public static void scrollToTop(InstrumentationTestCase test, Activity activity, ViewGroup v) {
163         View firstChild;
164         int firstId = Integer.MIN_VALUE;
165         int firstTop = Integer.MIN_VALUE;
166         int prevId;
167         int prevTop;
168         do {
169             prevId = firstId;
170             prevTop = firstTop;
171             TouchUtils.dragQuarterScreenDown(test, activity);
172             firstChild = v.getChildAt(0);
173             firstId = firstChild.getId();
174             firstTop = firstChild.getTop();
175         } while ((prevId != firstId) || (prevTop != firstTop));
176     }
177 
178     /**
179      * Simulate touching the center of a view and dragging to the bottom of the screen.
180      *
181      * @param test The test case that is being run
182      * @param v The view that should be dragged
183      *
184      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
185      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
186      * configuring the Activity under test
187      */
188     @Deprecated
dragViewToBottom(ActivityInstrumentationTestCase test, View v)189     public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v) {
190         dragViewToBottom(test, test.getActivity(), v, 4);
191     }
192 
193     /**
194      * Simulate touching the center of a view and dragging to the bottom of the screen.
195      *
196      * @param test The test case that is being run
197      * @param activity The activity that is in the foreground of the test case
198      * @param v The view that should be dragged
199      */
dragViewToBottom(InstrumentationTestCase test, Activity activity, View v)200     public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v) {
201         dragViewToBottom(test, activity, v, 4);
202     }
203 
204     /**
205      * Simulate touching the center of a view and dragging to the bottom of the screen.
206      *
207      * @param test The test case that is being run
208      * @param v The view that should be dragged
209      * @param stepCount How many move steps to include in the drag
210      *
211      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
212      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
213      * configuring the Activity under test
214      */
215     @Deprecated
dragViewToBottom(ActivityInstrumentationTestCase test, View v, int stepCount)216     public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v,
217             int stepCount) {
218         dragViewToBottom(test, test.getActivity(), v, stepCount);
219     }
220 
221     /**
222      * Simulate touching the center of a view and dragging to the bottom of the screen.
223      *
224      * @param test The test case that is being run
225      * @param activity The activity that is in the foreground of the test case
226      * @param v The view that should be dragged
227      * @param stepCount How many move steps to include in the drag
228      */
dragViewToBottom(InstrumentationTestCase test, Activity activity, View v, int stepCount)229     public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v,
230             int stepCount) {
231         int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
232 
233         int[] xy = new int[2];
234         v.getLocationOnScreen(xy);
235 
236         final int viewWidth = v.getWidth();
237         final int viewHeight = v.getHeight();
238 
239         final float x = xy[0] + (viewWidth / 2.0f);
240         float fromY = xy[1] + (viewHeight / 2.0f);
241         float toY = screenHeight - 1;
242 
243         drag(test, x, x, fromY, toY, stepCount);
244     }
245 
246     /**
247      * Simulate touching the center of a view and releasing quickly (before the tap timeout).
248      *
249      * @param test The test case that is being run
250      * @param v The view that should be clicked
251      */
tapView(InstrumentationTestCase test, View v)252     public static void tapView(InstrumentationTestCase test, View v) {
253         int[] xy = new int[2];
254         v.getLocationOnScreen(xy);
255 
256         final int viewWidth = v.getWidth();
257         final int viewHeight = v.getHeight();
258 
259         final float x = xy[0] + (viewWidth / 2.0f);
260         float y = xy[1] + (viewHeight / 2.0f);
261 
262         Instrumentation inst = test.getInstrumentation();
263 
264         long downTime = SystemClock.uptimeMillis();
265         long eventTime = SystemClock.uptimeMillis();
266 
267         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
268                 MotionEvent.ACTION_DOWN, x, y, 0);
269         inst.sendPointerSync(event);
270         inst.waitForIdleSync();
271 
272         eventTime = SystemClock.uptimeMillis();
273         final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
274         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
275                 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
276         inst.sendPointerSync(event);
277         inst.waitForIdleSync();
278 
279         eventTime = SystemClock.uptimeMillis();
280         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
281         inst.sendPointerSync(event);
282         inst.waitForIdleSync();
283     }
284 
285     /**
286      * Simulate touching the center of a view and cancelling (so no onClick should
287      * fire, etc).
288      *
289      * @param test The test case that is being run
290      * @param v The view that should be clicked
291      */
touchAndCancelView(InstrumentationTestCase test, View v)292     public static void touchAndCancelView(InstrumentationTestCase test, View v) {
293         int[] xy = new int[2];
294         v.getLocationOnScreen(xy);
295 
296         final int viewWidth = v.getWidth();
297         final int viewHeight = v.getHeight();
298 
299         final float x = xy[0] + (viewWidth / 2.0f);
300         float y = xy[1] + (viewHeight / 2.0f);
301 
302         Instrumentation inst = test.getInstrumentation();
303 
304         long downTime = SystemClock.uptimeMillis();
305         long eventTime = SystemClock.uptimeMillis();
306 
307         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
308                 MotionEvent.ACTION_DOWN, x, y, 0);
309         inst.sendPointerSync(event);
310         inst.waitForIdleSync();
311 
312         eventTime = SystemClock.uptimeMillis();
313         final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
314         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL,
315                 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
316         inst.sendPointerSync(event);
317         inst.waitForIdleSync();
318 
319     }
320 
321     /**
322      * Simulate touching the center of a view and releasing.
323      *
324      * @param test The test case that is being run
325      * @param v The view that should be clicked
326      */
clickView(InstrumentationTestCase test, View v)327     public static void clickView(InstrumentationTestCase test, View v) {
328         int[] xy = new int[2];
329         v.getLocationOnScreen(xy);
330 
331         final int viewWidth = v.getWidth();
332         final int viewHeight = v.getHeight();
333 
334         final float x = xy[0] + (viewWidth / 2.0f);
335         float y = xy[1] + (viewHeight / 2.0f);
336 
337         Instrumentation inst = test.getInstrumentation();
338 
339         long downTime = SystemClock.uptimeMillis();
340         long eventTime = SystemClock.uptimeMillis();
341 
342         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
343                 MotionEvent.ACTION_DOWN, x, y, 0);
344         inst.sendPointerSync(event);
345         inst.waitForIdleSync();
346 
347 
348         eventTime = SystemClock.uptimeMillis();
349         final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
350         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
351                 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
352         inst.sendPointerSync(event);
353         inst.waitForIdleSync();
354 
355         eventTime = SystemClock.uptimeMillis();
356         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
357         inst.sendPointerSync(event);
358         inst.waitForIdleSync();
359 
360         try {
361             Thread.sleep(1000);
362         } catch (InterruptedException e) {
363             e.printStackTrace();
364         }
365     }
366 
367     /**
368      * Simulate touching the center of a view, holding until it is a long press, and then releasing.
369      *
370      * @param test The test case that is being run
371      * @param v The view that should be clicked
372      *
373      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
374      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
375      * configuring the Activity under test
376      */
377     @Deprecated
longClickView(ActivityInstrumentationTestCase test, View v)378     public static void longClickView(ActivityInstrumentationTestCase test, View v) {
379         longClickView((InstrumentationTestCase) test, v);
380     }
381 
382     /**
383      * Simulate touching the center of a view, holding until it is a long press, and then releasing.
384      *
385      * @param test The test case that is being run
386      * @param v The view that should be clicked
387      */
longClickView(InstrumentationTestCase test, View v)388     public static void longClickView(InstrumentationTestCase test, View v) {
389         int[] xy = new int[2];
390         v.getLocationOnScreen(xy);
391 
392         final int viewWidth = v.getWidth();
393         final int viewHeight = v.getHeight();
394 
395         final float x = xy[0] + (viewWidth / 2.0f);
396         float y = xy[1] + (viewHeight / 2.0f);
397 
398         Instrumentation inst = test.getInstrumentation();
399 
400         long downTime = SystemClock.uptimeMillis();
401         long eventTime = SystemClock.uptimeMillis();
402 
403         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
404                 MotionEvent.ACTION_DOWN, x, y, 0);
405         inst.sendPointerSync(event);
406         inst.waitForIdleSync();
407 
408         eventTime = SystemClock.uptimeMillis();
409         final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
410         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
411                 x + touchSlop / 2, y + touchSlop / 2, 0);
412         inst.sendPointerSync(event);
413         inst.waitForIdleSync();
414 
415         try {
416             Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f));
417         } catch (InterruptedException e) {
418             e.printStackTrace();
419         }
420 
421         eventTime = SystemClock.uptimeMillis();
422         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
423         inst.sendPointerSync(event);
424         inst.waitForIdleSync();
425     }
426 
427     /**
428      * Simulate touching the center of a view and dragging to the top of the screen.
429      *
430      * @param test The test case that is being run
431      * @param v The view that should be dragged
432      *
433      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
434      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
435      * configuring the Activity under test
436      */
437     @Deprecated
dragViewToTop(ActivityInstrumentationTestCase test, View v)438     public static void dragViewToTop(ActivityInstrumentationTestCase test, View v) {
439         dragViewToTop((InstrumentationTestCase) test, v, 4);
440     }
441 
442     /**
443      * Simulate touching the center of a view and dragging to the top of the screen.
444      *
445      * @param test The test case that is being run
446      * @param v The view that should be dragged
447      * @param stepCount How many move steps to include in the drag
448      *
449      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
450      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
451      * configuring the Activity under test
452      */
453     @Deprecated
dragViewToTop(ActivityInstrumentationTestCase test, View v, int stepCount)454     public static void dragViewToTop(ActivityInstrumentationTestCase test, View v, int stepCount) {
455         dragViewToTop((InstrumentationTestCase) test, v, stepCount);
456     }
457 
458     /**
459      * Simulate touching the center of a view and dragging to the top of the screen.
460      *
461      * @param test The test case that is being run
462      * @param v The view that should be dragged
463      */
dragViewToTop(InstrumentationTestCase test, View v)464     public static void dragViewToTop(InstrumentationTestCase test, View v) {
465         dragViewToTop(test, v, 4);
466     }
467 
468     /**
469      * Simulate touching the center of a view and dragging to the top of the screen.
470      *
471      * @param test The test case that is being run
472      * @param v The view that should be dragged
473      * @param stepCount How many move steps to include in the drag
474      */
dragViewToTop(InstrumentationTestCase test, View v, int stepCount)475     public static void dragViewToTop(InstrumentationTestCase test, View v, int stepCount) {
476         int[] xy = new int[2];
477         v.getLocationOnScreen(xy);
478 
479         final int viewWidth = v.getWidth();
480         final int viewHeight = v.getHeight();
481 
482         final float x = xy[0] + (viewWidth / 2.0f);
483         float fromY = xy[1] + (viewHeight / 2.0f);
484         float toY = 0;
485 
486         drag(test, x, x, fromY, toY, stepCount);
487     }
488 
489     /**
490      * Get the location of a view. Use the gravity param to specify which part of the view to
491      * return.
492      *
493      * @param v View to find
494      * @param gravity A combination of (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL,
495      *        RIGHT)
496      * @param xy Result
497      */
getStartLocation(View v, int gravity, int[] xy)498     private static void getStartLocation(View v, int gravity, int[] xy) {
499         v.getLocationOnScreen(xy);
500 
501         final int viewWidth = v.getWidth();
502         final int viewHeight = v.getHeight();
503 
504         switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
505         case Gravity.TOP:
506             break;
507         case Gravity.CENTER_VERTICAL:
508             xy[1] += viewHeight / 2;
509             break;
510         case Gravity.BOTTOM:
511             xy[1] += viewHeight - 1;
512             break;
513         default:
514             // Same as top -- do nothing
515         }
516 
517         switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
518         case Gravity.LEFT:
519             break;
520         case Gravity.CENTER_HORIZONTAL:
521             xy[0] += viewWidth / 2;
522             break;
523         case Gravity.RIGHT:
524             xy[0] += viewWidth - 1;
525             break;
526         default:
527             // Same as left -- do nothing
528         }
529     }
530 
531     /**
532      * Simulate touching a view and dragging it by the specified amount.
533      *
534      * @param test The test case that is being run
535      * @param v The view that should be dragged
536      * @param gravity Which part of the view to use for the initial down event. A combination of
537      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
538      * @param deltaX Amount to drag horizontally in pixels
539      * @param deltaY Amount to drag vertically in pixels
540      *
541      * @return distance in pixels covered by the drag
542      *
543      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
544      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
545      * configuring the Activity under test
546      */
547     @Deprecated
dragViewBy(ActivityInstrumentationTestCase test, View v, int gravity, int deltaX, int deltaY)548     public static int dragViewBy(ActivityInstrumentationTestCase test, View v, int gravity,
549             int deltaX, int deltaY) {
550         return dragViewBy((InstrumentationTestCase) test, v, gravity, deltaX, deltaY);
551     }
552 
553     /**
554      * Simulate touching a view and dragging it by the specified amount.
555      *
556      * @param test The test case that is being run
557      * @param v The view that should be dragged
558      * @param gravity Which part of the view to use for the initial down event. A combination of
559      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
560      * @param deltaX Amount to drag horizontally in pixels
561      * @param deltaY Amount to drag vertically in pixels
562      *
563      * @return distance in pixels covered by the drag
564      *
565      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
566      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
567      * configuring the Activity under test
568      */
569     @Deprecated
dragViewBy(InstrumentationTestCase test, View v, int gravity, int deltaX, int deltaY)570     public static int dragViewBy(InstrumentationTestCase test, View v, int gravity, int deltaX,
571             int deltaY) {
572         int[] xy = new int[2];
573 
574         getStartLocation(v, gravity, xy);
575 
576         final int fromX = xy[0];
577         final int fromY = xy[1];
578 
579         int distance = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
580 
581         drag(test, fromX, fromX + deltaX, fromY, fromY + deltaY, distance);
582 
583         return distance;
584     }
585 
586     /**
587      * Simulate touching a view and dragging it to a specified location.
588      *
589      * @param test The test case that is being run
590      * @param v The view that should be dragged
591      * @param gravity Which part of the view to use for the initial down event. A combination of
592      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
593      * @param toX Final location of the view after dragging
594      * @param toY Final location of the view after dragging
595      *
596      * @return distance in pixels covered by the drag
597      *
598      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
599      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
600      * configuring the Activity under test
601      */
602     @Deprecated
dragViewTo(ActivityInstrumentationTestCase test, View v, int gravity, int toX, int toY)603     public static int dragViewTo(ActivityInstrumentationTestCase test, View v, int gravity, int toX,
604             int toY) {
605         return dragViewTo((InstrumentationTestCase) test, v, gravity, toX, toY);
606     }
607 
608     /**
609      * Simulate touching a view and dragging it to a specified location.
610      *
611      * @param test The test case that is being run
612      * @param v The view that should be dragged
613      * @param gravity Which part of the view to use for the initial down event. A combination of
614      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
615      * @param toX Final location of the view after dragging
616      * @param toY Final location of the view after dragging
617      *
618      * @return distance in pixels covered by the drag
619      */
dragViewTo(InstrumentationTestCase test, View v, int gravity, int toX, int toY)620     public static int dragViewTo(InstrumentationTestCase test, View v, int gravity, int toX,
621             int toY) {
622         int[] xy = new int[2];
623 
624         getStartLocation(v, gravity, xy);
625 
626         final int fromX = xy[0];
627         final int fromY = xy[1];
628 
629         int deltaX = fromX - toX;
630         int deltaY = fromY - toY;
631 
632         int distance = (int)Math.sqrt(deltaX * deltaX + deltaY * deltaY);
633         drag(test, fromX, toX, fromY, toY, distance);
634 
635         return distance;
636     }
637 
638     /**
639      * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
640      *
641      * @param test The test case that is being run
642      * @param v The view that should be dragged
643      * @param gravity Which part of the view to use for the initial down event. A combination of
644      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
645      * @param toX Final location of the view after dragging
646      *
647      * @return distance in pixels covered by the drag
648      *
649      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
650      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
651      * configuring the Activity under test
652      */
653     @Deprecated
dragViewToX(ActivityInstrumentationTestCase test, View v, int gravity, int toX)654     public static int dragViewToX(ActivityInstrumentationTestCase test, View v, int gravity,
655             int toX) {
656         return dragViewToX((InstrumentationTestCase) test, v, gravity, toX);
657     }
658 
659     /**
660      * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
661      *
662      * @param test The test case that is being run
663      * @param v The view that should be dragged
664      * @param gravity Which part of the view to use for the initial down event. A combination of
665      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
666      * @param toX Final location of the view after dragging
667      *
668      * @return distance in pixels covered by the drag
669      */
dragViewToX(InstrumentationTestCase test, View v, int gravity, int toX)670     public static int dragViewToX(InstrumentationTestCase test, View v, int gravity, int toX) {
671         int[] xy = new int[2];
672 
673         getStartLocation(v, gravity, xy);
674 
675         final int fromX = xy[0];
676         final int fromY = xy[1];
677 
678         int deltaX = fromX - toX;
679 
680         drag(test, fromX, toX, fromY, fromY, deltaX);
681 
682         return deltaX;
683     }
684 
685     /**
686      * Simulate touching a view and dragging it to a specified location. Only moves vertically.
687      *
688      * @param test The test case that is being run
689      * @param v The view that should be dragged
690      * @param gravity Which part of the view to use for the initial down event. A combination of
691      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
692      * @param toY Final location of the view after dragging
693      *
694      * @return distance in pixels covered by the drag
695      *
696      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
697      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
698      * configuring the Activity under test
699      */
700     @Deprecated
dragViewToY(ActivityInstrumentationTestCase test, View v, int gravity, int toY)701     public static int dragViewToY(ActivityInstrumentationTestCase test, View v, int gravity,
702             int toY) {
703         return dragViewToY((InstrumentationTestCase) test, v, gravity, toY);
704     }
705 
706     /**
707      * Simulate touching a view and dragging it to a specified location. Only moves vertically.
708      *
709      * @param test The test case that is being run
710      * @param v The view that should be dragged
711      * @param gravity Which part of the view to use for the initial down event. A combination of
712      *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
713      * @param toY Final location of the view after dragging
714      *
715      * @return distance in pixels covered by the drag
716      */
dragViewToY(InstrumentationTestCase test, View v, int gravity, int toY)717     public static int dragViewToY(InstrumentationTestCase test, View v, int gravity, int toY) {
718         int[] xy = new int[2];
719 
720         getStartLocation(v, gravity, xy);
721 
722         final int fromX = xy[0];
723         final int fromY = xy[1];
724 
725         int deltaY = fromY - toY;
726 
727         drag(test, fromX, fromX, fromY, toY, deltaY);
728 
729         return deltaY;
730     }
731 
732 
733     /**
734      * Simulate touching a specific location and dragging to a new location.
735      *
736      * @param test The test case that is being run
737      * @param fromX X coordinate of the initial touch, in screen coordinates
738      * @param toX Xcoordinate of the drag destination, in screen coordinates
739      * @param fromY X coordinate of the initial touch, in screen coordinates
740      * @param toY Y coordinate of the drag destination, in screen coordinates
741      * @param stepCount How many move steps to include in the drag
742      *
743      * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
744      * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
745      * configuring the Activity under test
746      */
747     @Deprecated
drag(ActivityInstrumentationTestCase test, float fromX, float toX, float fromY, float toY, int stepCount)748     public static void drag(ActivityInstrumentationTestCase test, float fromX, float toX,
749             float fromY, float toY, int stepCount) {
750         drag((InstrumentationTestCase) test, fromX, toX, fromY, toY, stepCount);
751     }
752 
753     /**
754      * Simulate touching a specific location and dragging to a new location.
755      *
756      * @param test The test case that is being run
757      * @param fromX X coordinate of the initial touch, in screen coordinates
758      * @param toX Xcoordinate of the drag destination, in screen coordinates
759      * @param fromY X coordinate of the initial touch, in screen coordinates
760      * @param toY Y coordinate of the drag destination, in screen coordinates
761      * @param stepCount How many move steps to include in the drag
762      */
drag(InstrumentationTestCase test, float fromX, float toX, float fromY, float toY, int stepCount)763     public static void drag(InstrumentationTestCase test, float fromX, float toX, float fromY,
764             float toY, int stepCount) {
765         Instrumentation inst = test.getInstrumentation();
766 
767         long downTime = SystemClock.uptimeMillis();
768         long eventTime = SystemClock.uptimeMillis();
769 
770         float y = fromY;
771         float x = fromX;
772 
773         float yStep = (toY - fromY) / stepCount;
774         float xStep = (toX - fromX) / stepCount;
775 
776         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
777                 MotionEvent.ACTION_DOWN, x, y, 0);
778         inst.sendPointerSync(event);
779         inst.waitForIdleSync();
780 
781         for (int i = 0; i < stepCount; ++i) {
782             y += yStep;
783             x += xStep;
784             eventTime = SystemClock.uptimeMillis();
785             event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
786             inst.sendPointerSync(event);
787             inst.waitForIdleSync();
788         }
789 
790         eventTime = SystemClock.uptimeMillis();
791         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
792         inst.sendPointerSync(event);
793         inst.waitForIdleSync();
794     }
795 }
796