/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.test;

import android.app.Activity;
import android.app.Instrumentation;
import android.graphics.Point;
import android.os.SystemClock;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;

/**
 * Reusable methods for generating touch events. These methods can be used with
 * InstrumentationTestCase or ActivityInstrumentationTestCase2 to simulate user interaction with
 * the application through a touch screen.
 */
public class TouchUtils {
    
    /**
     * Simulate touching in the center of the screen and dragging one quarter of the way down
     * @param test The test case that is being run
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void dragQuarterScreenDown(ActivityInstrumentationTestCase test) {
        dragQuarterScreenDown(test, test.getActivity());
    }
    
    /**
     * Simulate touching in the center of the screen and dragging one quarter of the way down
     * @param test The test case that is being run
     * @param activity The activity that is in the foreground of the test case
     */
    public static void dragQuarterScreenDown(InstrumentationTestCase test, Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        final Point size = new Point();
        display.getSize(size);
        
        final float x = size.x / 2.0f;
        final float fromY = size.y * 0.5f;
        final float toY = size.y * 0.75f;
      
        drag(test, x, x, fromY, toY, 4);
    }
    
    /**
     * Simulate touching in the center of the screen and dragging one quarter of the way up
     * @param test The test case that is being run
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void dragQuarterScreenUp(ActivityInstrumentationTestCase test) {
        dragQuarterScreenUp(test, test.getActivity());
    }
    
    /**
     * Simulate touching in the center of the screen and dragging one quarter of the way up
     * @param test The test case that is being run
     * @param activity The activity that is in the foreground of the test case
     */
    public static void dragQuarterScreenUp(InstrumentationTestCase test, Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        final Point size = new Point();
        display.getSize(size);
        
        final float x = size.x / 2.0f;
        final float fromY = size.y * 0.5f;
        final float toY = size.y * 0.25f;
      
        drag(test, x, x, fromY, toY, 4);
    }
    
    /**
     * Scroll a ViewGroup to the bottom by repeatedly calling
     * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
     * 
     * @param test The test case that is being run
     * @param v The ViewGroup that should be dragged
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void scrollToBottom(ActivityInstrumentationTestCase test, ViewGroup v) {
        scrollToBottom(test, test.getActivity(), v);
    }
    
    /**
     * Scroll a ViewGroup to the bottom by repeatedly calling
     * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
     * 
     * @param test The test case that is being run
     * @param activity The activity that is in the foreground of the test case
     * @param v The ViewGroup that should be dragged
     */
    public static void scrollToBottom(InstrumentationTestCase test, Activity activity,
            ViewGroup v) {
        ViewStateSnapshot prev;
        ViewStateSnapshot next = new ViewStateSnapshot(v);
        do {
            prev = next;
            TouchUtils.dragQuarterScreenUp(test, activity);
            next = new ViewStateSnapshot(v);
        } while (!prev.equals(next));
    }

    /**
     * Scroll a ViewGroup to the top by repeatedly calling
     * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
     * 
     * @param test The test case that is being run
     * @param v The ViewGroup that should be dragged
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void scrollToTop(ActivityInstrumentationTestCase test, ViewGroup v) {
        scrollToTop(test, test.getActivity(), v);
    }
    
    /**
     * Scroll a ViewGroup to the top by repeatedly calling
     * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
     * 
     * @param test The test case that is being run
     * @param activity The activity that is in the foreground of the test case
     * @param v The ViewGroup that should be dragged
     */
    public static void scrollToTop(InstrumentationTestCase test, Activity activity, ViewGroup v) {
        ViewStateSnapshot prev;
        ViewStateSnapshot next = new ViewStateSnapshot(v);
        do {
            prev = next;
            TouchUtils.dragQuarterScreenDown(test, activity);
            next = new ViewStateSnapshot(v);
        } while (!prev.equals(next));
    }
    
    /**
     * Simulate touching the center of a view and dragging to the bottom of the screen.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v) {
        dragViewToBottom(test, test.getActivity(), v, 4);
    }
    
    /**
     * Simulate touching the center of a view and dragging to the bottom of the screen.
     * 
     * @param test The test case that is being run
     * @param activity The activity that is in the foreground of the test case
     * @param v The view that should be dragged
     */
    public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v) {
        dragViewToBottom(test, activity, v, 4);
    }
    
    /**
     * Simulate touching the center of a view and dragging to the bottom of the screen.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param stepCount How many move steps to include in the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v,
            int stepCount) {
        dragViewToBottom(test, test.getActivity(), v, stepCount);
    }
    
    /**
     * Simulate touching the center of a view and dragging to the bottom of the screen.
     * 
     * @param test The test case that is being run
     * @param activity The activity that is in the foreground of the test case
     * @param v The view that should be dragged
     * @param stepCount How many move steps to include in the drag
     */
    public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v,
            int stepCount) {
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();

        int[] xy = new int[2];
        v.getLocationOnScreen(xy);
        
        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();
        
        final float x = xy[0] + (viewWidth / 2.0f);
        float fromY = xy[1] + (viewHeight / 2.0f);
        float toY = screenHeight - 1;
        
        drag(test, x, x, fromY, toY, stepCount);
    }

    /**
     * Simulate touching the center of a view and releasing quickly (before the tap timeout).
     * 
     * @param test The test case that is being run
     * @param v The view that should be clicked
     */
    public static void tapView(InstrumentationTestCase test, View v) {
        int[] xy = new int[2];
        v.getLocationOnScreen(xy);
        
        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();
        
        final float x = xy[0] + (viewWidth / 2.0f);
        float y = xy[1] + (viewHeight / 2.0f);
        
        Instrumentation inst = test.getInstrumentation();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();
        
        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();

        eventTime = SystemClock.uptimeMillis();
        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();

        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
    }

    /**
     * Simulate touching the center of a view and cancelling (so no onClick should
     * fire, etc).
     *
     * @param test The test case that is being run
     * @param v The view that should be clicked
     */
    public static void touchAndCancelView(InstrumentationTestCase test, View v) {
        int[] xy = new int[2];
        v.getLocationOnScreen(xy);

        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();

        final float x = xy[0] + (viewWidth / 2.0f);
        float y = xy[1] + (viewHeight / 2.0f);

        Instrumentation inst = test.getInstrumentation();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();

        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();

        eventTime = SystemClock.uptimeMillis();
        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL,
                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();

    }

    /**
     * Simulate touching the center of a view and releasing.
     * 
     * @param test The test case that is being run
     * @param v The view that should be clicked
     */
    public static void clickView(InstrumentationTestCase test, View v) {
        int[] xy = new int[2];
        v.getLocationOnScreen(xy);
        
        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();
        
        final float x = xy[0] + (viewWidth / 2.0f);
        float y = xy[1] + (viewHeight / 2.0f);
        
        Instrumentation inst = test.getInstrumentation();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();
        
        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
        

        eventTime = SystemClock.uptimeMillis();
        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();

        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * Simulate touching the center of a view, holding until it is a long press, and then releasing.
     * 
     * @param test The test case that is being run
     * @param v The view that should be clicked
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void longClickView(ActivityInstrumentationTestCase test, View v) {
        longClickView((InstrumentationTestCase) test, v);
    }

    /**
     * Simulate touching the center of a view, holding until it is a long press, and then releasing.
     * 
     * @param test The test case that is being run
     * @param v The view that should be clicked
     */
    public static void longClickView(InstrumentationTestCase test, View v) {
        int[] xy = new int[2];
        v.getLocationOnScreen(xy);
        
        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();
        
        final float x = xy[0] + (viewWidth / 2.0f);
        float y = xy[1] + (viewHeight / 2.0f);
        
        Instrumentation inst = test.getInstrumentation();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();

        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();

        eventTime = SystemClock.uptimeMillis();
        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
                x + touchSlop / 2, y + touchSlop / 2, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
        
        try {
            Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
    }

    /**
     * Simulate touching the center of a view and dragging to the top of the screen.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void dragViewToTop(ActivityInstrumentationTestCase test, View v) {
        dragViewToTop((InstrumentationTestCase) test, v, 4);
    }
    
    /**
     * Simulate touching the center of a view and dragging to the top of the screen.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param stepCount How many move steps to include in the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void dragViewToTop(ActivityInstrumentationTestCase test, View v, int stepCount) {
        dragViewToTop((InstrumentationTestCase) test, v, stepCount);
    }
    
    /**
     * Simulate touching the center of a view and dragging to the top of the screen.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     */
    public static void dragViewToTop(InstrumentationTestCase test, View v) {
        dragViewToTop(test, v, 4);
    }
    
    /**
     * Simulate touching the center of a view and dragging to the top of the screen.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param stepCount How many move steps to include in the drag
     */
    public static void dragViewToTop(InstrumentationTestCase test, View v, int stepCount) {
        int[] xy = new int[2];
        v.getLocationOnScreen(xy);
        
        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();
        
        final float x = xy[0] + (viewWidth / 2.0f);
        float fromY = xy[1] + (viewHeight / 2.0f);
        float toY = 0;
        
        drag(test, x, x, fromY, toY, stepCount);
    }
    
    /**
     * Get the location of a view. Use the gravity param to specify which part of the view to
     * return.
     * 
     * @param v View to find
     * @param gravity A combination of (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL,
     *        RIGHT)
     * @param xy Result
     */
    private static void getStartLocation(View v, int gravity, int[] xy) {
        v.getLocationOnScreen(xy);

        final int viewWidth = v.getWidth();
        final int viewHeight = v.getHeight();
        
        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
        case Gravity.TOP:
            break;
        case Gravity.CENTER_VERTICAL:
            xy[1] += viewHeight / 2;
            break;
        case Gravity.BOTTOM:
            xy[1] += viewHeight - 1;
            break;
        default:
            // Same as top -- do nothing
        }
        
        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
        case Gravity.LEFT:
            break;
        case Gravity.CENTER_HORIZONTAL:
            xy[0] += viewWidth / 2;
            break;
        case Gravity.RIGHT:
            xy[0] += viewWidth - 1;
            break;
        default:
            // Same as left -- do nothing
        }
    }

    /**
     * Simulate touching a view and dragging it by the specified amount.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param deltaX Amount to drag horizontally in pixels
     * @param deltaY Amount to drag vertically in pixels
     * 
     * @return distance in pixels covered by the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static int dragViewBy(ActivityInstrumentationTestCase test, View v, int gravity,
            int deltaX, int deltaY) {
        return dragViewBy((InstrumentationTestCase) test, v, gravity, deltaX, deltaY);
    }
    
    /**
     * Simulate touching a view and dragging it by the specified amount.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param deltaX Amount to drag horizontally in pixels
     * @param deltaY Amount to drag vertically in pixels
     * 
     * @return distance in pixels covered by the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static int dragViewBy(InstrumentationTestCase test, View v, int gravity, int deltaX,
            int deltaY) {
        int[] xy = new int[2];
        
        getStartLocation(v, gravity, xy);

        final int fromX = xy[0];
        final int fromY = xy[1];
        
        int distance = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);

        drag(test, fromX, fromX + deltaX, fromY, fromY + deltaY, distance);

        return distance;
    }
    
    /**
     * Simulate touching a view and dragging it to a specified location.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param toX Final location of the view after dragging
     * @param toY Final location of the view after dragging
     * 
     * @return distance in pixels covered by the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static int dragViewTo(ActivityInstrumentationTestCase test, View v, int gravity, int toX,
            int toY) {
        return dragViewTo((InstrumentationTestCase) test, v, gravity, toX, toY);
    }

    /**
     * Simulate touching a view and dragging it to a specified location.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param toX Final location of the view after dragging
     * @param toY Final location of the view after dragging
     * 
     * @return distance in pixels covered by the drag
     */
    public static int dragViewTo(InstrumentationTestCase test, View v, int gravity, int toX,
            int toY) {
        int[] xy = new int[2];

        getStartLocation(v, gravity, xy);
        
        final int fromX = xy[0];
        final int fromY = xy[1];
        
        int deltaX = fromX - toX;
        int deltaY = fromY - toY;
        
        int distance = (int)Math.sqrt(deltaX * deltaX + deltaY * deltaY);
        drag(test, fromX, toX, fromY, toY, distance);
        
        return distance;
    }

    /**
     * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param toX Final location of the view after dragging
     * 
     * @return distance in pixels covered by the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static int dragViewToX(ActivityInstrumentationTestCase test, View v, int gravity,
            int toX) {
        return dragViewToX((InstrumentationTestCase) test, v, gravity, toX);
    }

    /**
     * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param toX Final location of the view after dragging
     * 
     * @return distance in pixels covered by the drag
     */
    public static int dragViewToX(InstrumentationTestCase test, View v, int gravity, int toX) {
        int[] xy = new int[2];

        getStartLocation(v, gravity, xy);
        
        final int fromX = xy[0];
        final int fromY = xy[1];
        
        int deltaX = fromX - toX;

        drag(test, fromX, toX, fromY, fromY, deltaX);
        
        return deltaX;
    }
    
    /**
     * Simulate touching a view and dragging it to a specified location. Only moves vertically.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param toY Final location of the view after dragging
     * 
     * @return distance in pixels covered by the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static int dragViewToY(ActivityInstrumentationTestCase test, View v, int gravity,
            int toY) {
        return dragViewToY((InstrumentationTestCase) test, v, gravity, toY);
    }
    
    /**
     * Simulate touching a view and dragging it to a specified location. Only moves vertically.
     * 
     * @param test The test case that is being run
     * @param v The view that should be dragged
     * @param gravity Which part of the view to use for the initial down event. A combination of
     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
     * @param toY Final location of the view after dragging
     * 
     * @return distance in pixels covered by the drag
     */
    public static int dragViewToY(InstrumentationTestCase test, View v, int gravity, int toY) {
        int[] xy = new int[2];

        getStartLocation(v, gravity, xy);
       
        final int fromX = xy[0];
        final int fromY = xy[1];
        
        int deltaY = fromY - toY;

        drag(test, fromX, fromX, fromY, toY, deltaY);
        
        return deltaY;
    }
    

    /**
     * Simulate touching a specific location and dragging to a new location.
     * 
     * @param test The test case that is being run
     * @param fromX X coordinate of the initial touch, in screen coordinates
     * @param toX Xcoordinate of the drag destination, in screen coordinates
     * @param fromY X coordinate of the initial touch, in screen coordinates
     * @param toY Y coordinate of the drag destination, in screen coordinates
     * @param stepCount How many move steps to include in the drag
     *
     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
     * configuring the Activity under test
     */
    @Deprecated
    public static void drag(ActivityInstrumentationTestCase test, float fromX, float toX,
            float fromY, float toY, int stepCount) {
        drag((InstrumentationTestCase) test, fromX, toX, fromY, toY, stepCount);
    }
    
    /**
     * Simulate touching a specific location and dragging to a new location.
     * 
     * @param test The test case that is being run
     * @param fromX X coordinate of the initial touch, in screen coordinates
     * @param toX Xcoordinate of the drag destination, in screen coordinates
     * @param fromY X coordinate of the initial touch, in screen coordinates
     * @param toY Y coordinate of the drag destination, in screen coordinates
     * @param stepCount How many move steps to include in the drag
     */
    public static void drag(InstrumentationTestCase test, float fromX, float toX, float fromY,
            float toY, int stepCount) {
        Instrumentation inst = test.getInstrumentation();

        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();

        float y = fromY;
        float x = fromX;
        
        float yStep = (toY - fromY) / stepCount;
        float xStep = (toX - fromX) / stepCount;

        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        inst.sendPointerSync(event);
        for (int i = 0; i < stepCount; ++i) {
            y += yStep;
            x += xStep;
            eventTime = SystemClock.uptimeMillis();
            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
            inst.sendPointerSync(event);
        }

        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
    }

    private static class ViewStateSnapshot {
        final View mFirst;
        final View mLast;
        final int mFirstTop;
        final int mLastBottom;
        final int mChildCount;
        private ViewStateSnapshot(ViewGroup viewGroup) {
            mChildCount = viewGroup.getChildCount();
            if (mChildCount == 0) {
                mFirst = mLast = null;
                mFirstTop = mLastBottom = Integer.MIN_VALUE;
            } else {
                mFirst = viewGroup.getChildAt(0);
                mLast = viewGroup.getChildAt(mChildCount - 1);
                mFirstTop = mFirst.getTop();
                mLastBottom = mLast.getBottom();
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            final ViewStateSnapshot that = (ViewStateSnapshot) o;
            return mFirstTop == that.mFirstTop &&
                    mLastBottom == that.mLastBottom &&
                    mFirst == that.mFirst &&
                    mLast == that.mLast &&
                    mChildCount == that.mChildCount;
        }

        @Override
        public int hashCode() {
            int result = mFirst != null ? mFirst.hashCode() : 0;
            result = 31 * result + (mLast != null ? mLast.hashCode() : 0);
            result = 31 * result + mFirstTop;
            result = 31 * result + mLastBottom;
            result = 31 * result + mChildCount;
            return result;
        }
    }
}
