Home | History | Annotate | Download | only in test
      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
     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      */
     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
     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      */
     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
    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      */
    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
    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      */
    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
    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      */
    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
    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      */
    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      */
    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      */
    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      */
    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
    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      */
    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
    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
    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      */
    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      */
    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      */
    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
    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
    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
    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      */
    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
    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      */
    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
    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      */
    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
    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      */
    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