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