10a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar/*
20a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
30a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar *
40a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
50a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * you may not use this file except in compliance with the License.
60a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * You may obtain a copy of the License at
70a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar *
80a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
90a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar *
100a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * Unless required by applicable law or agreed to in writing, software
110a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
120a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * See the License for the specific language governing permissions and
140a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * limitations under the License.
150a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar */
160a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
170a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarpackage android.support.v7.util;
180a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
190a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.app.Instrumentation;
200a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.os.SystemClock;
210a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.support.v7.widget.RecyclerView;
220a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.Gravity;
230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.MotionEvent;
240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.View;
250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.ViewConfiguration;
260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar/**
280a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * RV specific layout tests.
290a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar */
300a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarpublic class TouchUtils {
310a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void tapView(Instrumentation inst, RecyclerView recyclerView,
320a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            View v) {
330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
380a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
390a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
430a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
440a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
450a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
460a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
470a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
480a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
500a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
520a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
530a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
540a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
550a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
560a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
570a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
580a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
590a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
600a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
610a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
620a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
630a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void touchAndCancelView(Instrumentation inst, View v) {
640a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
650a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
660a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
670a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
680a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
690a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
700a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
710a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
720a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
730a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
740a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
750a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
760a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
770a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
780a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
790a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
800a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
810a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
820a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
830a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL,
840a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
850a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
860a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
870a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
880a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
890a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
900a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void clickView(Instrumentation inst, View v) {
910a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
920a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
930a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
940a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
950a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
960a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
970a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
980a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
990a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1000a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
1010a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
1020a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1030a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
1040a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
1050a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1060a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1070a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1080a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1090a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
1100a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
1110a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
1120a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1130a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1140a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1150a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1160a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
1170a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1180a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1190a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1200a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        try {
1210a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            Thread.sleep(1000);
1220a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        } catch (InterruptedException e) {
1230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            e.printStackTrace();
1240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
1250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void longClickView(Instrumentation inst, View v) {
1280a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
1290a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
1300a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1310a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
1320a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
1330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
1350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
1360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
1380a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
1390a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
1410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
1420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1430a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1440a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1450a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1460a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
1470a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
1480a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + touchSlop / 2, y + touchSlop / 2, 0);
1490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1500a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1520a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        try {
1530a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            Thread.sleep((long) (ViewConfiguration.getLongPressTimeout() * 1.5f));
1540a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        } catch (InterruptedException e) {
1550a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            e.printStackTrace();
1560a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
1570a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1580a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1590a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
1600a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1610a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1620a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1630a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1640a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void dragViewToTop(Instrumentation inst, View v) {
165959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        dragViewToTop(inst, v, calculateStepsForDistance(v.getTop()));
1660a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1670a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1680a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void dragViewToTop(Instrumentation inst, View v, int stepCount) {
1690a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
1700a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
1710a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1720a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
1730a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
1740a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1750a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
1760a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float fromY = xy[1] + (viewHeight / 2.0f);
1770a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float toY = 0;
1780a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1790a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        drag(inst, x, x, fromY, toY, stepCount);
1800a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1810a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1820a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    private static void getStartLocation(View v, int gravity, int[] xy) {
1830a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
1840a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1850a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
1860a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
1870a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1880a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
1890a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.TOP:
1900a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
1910a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.CENTER_VERTICAL:
1920a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[1] += viewHeight / 2;
1930a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
1940a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.BOTTOM:
1950a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[1] += viewHeight - 1;
1960a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
1970a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            default:
1980a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                // Same as top -- do nothing
1990a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
2000a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2010a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
2020a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.LEFT:
2030a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
2040a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.CENTER_HORIZONTAL:
2050a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[0] += viewWidth / 2;
2060a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
2070a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.RIGHT:
2080a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[0] += viewWidth - 1;
2090a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
2100a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            default:
2110a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                // Same as left -- do nothing
2120a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
2130a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2140a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2150a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static int dragViewTo(Instrumentation inst, View v, int gravity, int toX,
2160a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            int toY) {
2170a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
2180a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2190a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        getStartLocation(v, gravity, xy);
2200a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2210a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromX = xy[0];
2220a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromY = xy[1];
2230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaX = fromX - toX;
2250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaY = fromY - toY;
2260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int distance = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
228959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        drag(inst, fromX, toX, fromY, toY, calculateStepsForDistance(distance));
2290a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2300a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        return distance;
2310a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2320a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static int dragViewToX(Instrumentation inst, View v, int gravity, int toX) {
2340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
2350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        getStartLocation(v, gravity, xy);
2370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2380a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromX = xy[0];
2390a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromY = xy[1];
2400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaX = fromX - toX;
2420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
243959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        drag(inst, fromX, toX, fromY, fromY, calculateStepsForDistance(deltaX));
2440a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2450a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        return deltaX;
2460a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2470a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2480a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static int dragViewToY(Instrumentation inst, View v, int gravity, int toY) {
2490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
2500a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        getStartLocation(v, gravity, xy);
2520a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2530a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromX = xy[0];
2540a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromY = xy[1];
2550a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2560a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaY = fromY - toY;
2570a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
258959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        drag(inst, fromX, fromX, fromY, toY, calculateStepsForDistance(deltaY));
2590a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2600a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        return deltaY;
2610a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2620a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2630a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2640a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void drag(Instrumentation inst, float fromX, float toX, float fromY,
2650a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            float toY, int stepCount) {
2660a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
2670a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
2680a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2690a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = fromY;
2700a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float x = fromX;
2710a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2720a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float yStep = (toY - fromY) / stepCount;
2730a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float xStep = (toX - fromX) / stepCount;
2740a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2750a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
2760a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
2770a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
2780a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        for (int i = 0; i < stepCount; ++i) {
2790a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            y += yStep;
2800a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            x += xStep;
2810a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            eventTime = SystemClock.uptimeMillis();
2820a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
2830a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            inst.sendPointerSync(event);
2840a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
2850a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2860a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
2870a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
2880a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
2890a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
2900a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
291959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar
292959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar    private static int calculateStepsForDistance(int distance) {
293959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        return 1 + Math.abs(distance) / 10;
294959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar    }
2950a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar}
296