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.test.InstrumentationTestCase;
230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.Gravity;
240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.MotionEvent;
250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.View;
260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarimport android.view.ViewConfiguration;
270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
280a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar/**
290a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar * RV specific layout tests.
300a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar */
310a017072206f93474ccd2706e7983c2ff778b904Yigit Boyarpublic class TouchUtils {
320a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void tapView(Instrumentation inst, RecyclerView recyclerView,
330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            View v) {
340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
380a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
390a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
430a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
440a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
450a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
460a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
470a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
480a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
500a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
520a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
530a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
540a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
550a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
560a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
570a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
580a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
590a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
600a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
610a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
620a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
630a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
640a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void touchAndCancelView(Instrumentation inst, View v) {
650a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
660a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
670a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
680a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
690a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
700a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
710a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
720a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
730a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
740a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
750a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
760a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
770a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
780a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
790a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
800a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
810a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
820a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
830a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
840a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL,
850a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
860a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
870a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
880a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
890a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
900a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
910a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void clickView(Instrumentation inst, View v) {
920a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
930a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
940a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
950a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
960a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
970a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
980a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
990a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
1000a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1010a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
1020a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
1030a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1040a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
1050a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
1060a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1070a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1080a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1090a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1100a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
1110a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
1120a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
1130a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1140a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1150a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1160a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1170a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
1180a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1190a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1200a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1210a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        try {
1220a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            Thread.sleep(1000);
1230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        } catch (InterruptedException e) {
1240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            e.printStackTrace();
1250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
1260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1280a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void longClickView(Instrumentation inst, View v) {
1290a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
1300a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
1310a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1320a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
1330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
1340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
1360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = xy[1] + (viewHeight / 2.0f);
1370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1380a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
1390a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
1400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
1420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
1430a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1440a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1450a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1460a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1470a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
1480a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
1490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                x + touchSlop / 2, y + touchSlop / 2, 0);
1500a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1520a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1530a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        try {
1540a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            Thread.sleep((long) (ViewConfiguration.getLongPressTimeout() * 1.5f));
1550a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        } catch (InterruptedException e) {
1560a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            e.printStackTrace();
1570a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
1580a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1590a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
1600a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
1610a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
1620a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
1630a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1640a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1650a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void dragViewToTop(Instrumentation inst, View v) {
166959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        dragViewToTop(inst, v, calculateStepsForDistance(v.getTop()));
1670a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1680a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1690a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void dragViewToTop(Instrumentation inst, View v, int stepCount) {
1700a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
1710a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
1720a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1730a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
1740a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
1750a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1760a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final float x = xy[0] + (viewWidth / 2.0f);
1770a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float fromY = xy[1] + (viewHeight / 2.0f);
1780a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float toY = 0;
1790a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1800a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        drag(inst, x, x, fromY, toY, stepCount);
1810a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
1820a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1830a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    private static void getStartLocation(View v, int gravity, int[] xy) {
1840a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        v.getLocationOnScreen(xy);
1850a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1860a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewWidth = v.getWidth();
1870a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int viewHeight = v.getHeight();
1880a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
1890a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
1900a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.TOP:
1910a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
1920a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.CENTER_VERTICAL:
1930a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[1] += viewHeight / 2;
1940a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
1950a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.BOTTOM:
1960a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[1] += viewHeight - 1;
1970a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
1980a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            default:
1990a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                // Same as top -- do nothing
2000a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
2010a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2020a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
2030a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.LEFT:
2040a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
2050a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.CENTER_HORIZONTAL:
2060a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[0] += viewWidth / 2;
2070a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
2080a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            case Gravity.RIGHT:
2090a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                xy[0] += viewWidth - 1;
2100a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                break;
2110a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            default:
2120a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                // Same as left -- do nothing
2130a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
2140a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2150a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2160a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static int dragViewTo(Instrumentation inst, View v, int gravity, int toX,
2170a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            int toY) {
2180a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
2190a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2200a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        getStartLocation(v, gravity, xy);
2210a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2220a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromX = xy[0];
2230a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromY = xy[1];
2240a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2250a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaX = fromX - toX;
2260a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaY = fromY - toY;
2270a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2280a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int distance = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
229959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        drag(inst, fromX, toX, fromY, toY, calculateStepsForDistance(distance));
2300a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2310a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        return distance;
2320a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2330a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2340a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static int dragViewToX(Instrumentation inst, View v, int gravity, int toX) {
2350a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
2360a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2370a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        getStartLocation(v, gravity, xy);
2380a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2390a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromX = xy[0];
2400a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromY = xy[1];
2410a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2420a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaX = fromX - toX;
2430a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
244959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        drag(inst, fromX, toX, fromY, fromY, calculateStepsForDistance(deltaX));
2450a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2460a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        return deltaX;
2470a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2480a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2490a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static int dragViewToY(Instrumentation inst, View v, int gravity, int toY) {
2500a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int[] xy = new int[2];
2510a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2520a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        getStartLocation(v, gravity, xy);
2530a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2540a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromX = xy[0];
2550a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        final int fromY = xy[1];
2560a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2570a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        int deltaY = fromY - toY;
2580a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
259959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        drag(inst, fromX, fromX, fromY, toY, calculateStepsForDistance(deltaY));
2600a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2610a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        return deltaY;
2620a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
2630a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2640a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2650a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    public static void drag(Instrumentation inst, float fromX, float toX, float fromY,
2660a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            float toY, int stepCount) {
2670a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long downTime = SystemClock.uptimeMillis();
2680a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        long eventTime = SystemClock.uptimeMillis();
2690a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2700a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float y = fromY;
2710a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float x = fromX;
2720a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2730a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float yStep = (toY - fromY) / stepCount;
2740a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        float xStep = (toX - fromX) / stepCount;
2750a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2760a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
2770a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar                MotionEvent.ACTION_DOWN, x, y, 0);
2780a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
2790a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        for (int i = 0; i < stepCount; ++i) {
2800a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            y += yStep;
2810a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            x += xStep;
2820a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            eventTime = SystemClock.uptimeMillis();
2830a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
2840a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar            inst.sendPointerSync(event);
2850a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        }
2860a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar
2870a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        eventTime = SystemClock.uptimeMillis();
2880a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
2890a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.sendPointerSync(event);
2900a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar        inst.waitForIdleSync();
2910a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar    }
292959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar
293959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar    private static int calculateStepsForDistance(int distance) {
294959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar        return 1 + Math.abs(distance) / 10;
295959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar    }
2960a017072206f93474ccd2706e7983c2ff778b904Yigit Boyar}
297