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.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
     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      */
     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
     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      */
     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
    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      */
    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
    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      */
    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
    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      */
    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
    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      */
    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      */
    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      */
    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      */
    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
    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      */
    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
    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
    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      */
    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      */
    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      */
    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
    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
    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
    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      */
    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
    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      */
    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
    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      */
    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
    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      */
    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