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