TestTouchUtils.java revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.content.browser.test.util; 6 7import android.app.Activity; 8import android.app.Instrumentation; 9import android.os.SystemClock; 10import android.test.InstrumentationTestCase; 11import android.view.MotionEvent; 12import android.view.View; 13import android.view.ViewConfiguration; 14 15/** 16 * Collection of utilities for generating touch events. 17 * Based on android.test.TouchUtils, but slightly more flexible (allows to 18 * specify coordinates for longClick, splits drag operation in three stages, etc). 19 */ 20public class TestTouchUtils extends android.test.TouchUtils { 21 /** 22 * Returns the absolute location in screen coordinates from location relative 23 * to view. 24 * @param v The view the coordinates are relative to. 25 * @param x Relative x location. 26 * @param y Relative y location. 27 * @return the absolute x and y location in an array. 28 */ 29 public static int[] getAbsoluteLocationFromRelative(View v, int x, int y) { 30 int location[] = new int[2]; 31 v.getLocationOnScreen(location); 32 location[0] += x; 33 location[1] += y; 34 return location; 35 } 36 37 private static void sendAction(Instrumentation instrumentation, int action, long downTime, 38 float x, float y) { 39 long eventTime = SystemClock.uptimeMillis(); 40 MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, 0); 41 instrumentation.sendPointerSync(event); 42 instrumentation.waitForIdleSync(); 43 } 44 45 /** 46 * Sends (synchronously) a single click to an absolute screen coordinates. 47 * 48 * @param instrumentation Instrumentation object used by the test. 49 * @param x Screen absolute x location. 50 * @param y Screen absolute y location. 51 */ 52 public static void singleClick(Instrumentation instrumentation, float x, float y) { 53 long downTime = SystemClock.uptimeMillis(); 54 sendAction(instrumentation, MotionEvent.ACTION_DOWN, downTime, x, y); 55 sendAction(instrumentation, MotionEvent.ACTION_UP, downTime, x, y); 56 } 57 58 /** 59 * Sends (synchronously) a single click to the View at the specified coordinates. 60 * 61 * @param instrumentation Instrumentation object used by the test. 62 * @param v The view the coordinates are relative to. 63 * @param x Relative x location to the view. 64 * @param y Relative y location to the view. 65 */ 66 public static void singleClickView(Instrumentation instrumentation, View v, int x, int y) { 67 int location[] = getAbsoluteLocationFromRelative(v, x, y); 68 int absoluteX = location[0]; 69 int absoluteY = location[1]; 70 singleClick(instrumentation, absoluteX, absoluteY); 71 } 72 73 /** 74 * Sends (synchronously) a single click to the center of the View. 75 * 76 * @param instrumentation Instrumentation object used by the test. 77 * @param v The view the coordinates are relative to. 78 */ 79 public static void singleClickView(Instrumentation instrumentation, View v) { 80 int x = v.getWidth() / 2; 81 int y = v.getHeight() / 2; 82 singleClickView(instrumentation, v, x, y); 83 } 84 85 /** 86 * Sleeps for at least the length of the double tap timeout. 87 * 88 * @param instrumentation Instrumentation object used by the test. 89 */ 90 public static void sleepForDoubleTapTimeout(Instrumentation instrumentation) { 91 SystemClock.sleep((long)(ViewConfiguration.getDoubleTapTimeout() * 1.5)); 92 } 93 94 /** 95 * Sends (synchronously) a long click to the View at the specified coordinates. 96 * 97 * @param instrumentation Instrumentation object used by the test. 98 * @param v The view the coordinates are relative to. 99 * @param x Relative x location to the view. 100 * @param y Relative y location to the view. 101 */ 102 public static void longClickView(Instrumentation instrumentation, View v, int x, int y) { 103 int location[] = getAbsoluteLocationFromRelative(v, x, y); 104 int absoluteX = location[0]; 105 int absoluteY = location[1]; 106 107 long downTime = SystemClock.uptimeMillis(); 108 sendAction(instrumentation, MotionEvent.ACTION_DOWN, downTime, absoluteX, absoluteY); 109 SystemClock.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5)); 110 sendAction(instrumentation, MotionEvent.ACTION_UP, downTime, absoluteX, absoluteY); 111 } 112 113 /** 114 * Starts (synchronously) a drag motion. Normally followed by dragTo() and dragEnd(). 115 * 116 * @param instrumentation Instrumentation object used by the test. 117 * @param x The x location. 118 * @param y The y location. 119 * @return The downTime of the triggered event. 120 */ 121 public static long dragStart(Instrumentation instrumentation, float x, float y) { 122 long downTime = SystemClock.uptimeMillis(); 123 sendAction(instrumentation, MotionEvent.ACTION_DOWN, downTime, x, y); 124 return downTime; 125 } 126 127 /** 128 * Drags / moves (synchronously) to the specified coordinates. Normally preceeded by 129 * dragStart() and followed by dragEnd() 130 * 131 * @param instrumentation Instrumentation object used by the test. 132 * @param fromX The relative x-coordinate of the start point of the drag. 133 * @param toX The relative x-coordinate of the end point of the drag. 134 * @param fromY The relative y-coordinate of the start point of the drag. 135 * @param toY The relative y-coordinate of the end point of the drag. 136 * @param stepCount The total number of motion events that should be generated during the drag. 137 * @param downTime The initial time of the drag, in ms. 138 */ 139 public static void dragTo(Instrumentation instrumentation, float fromX, float toX, float fromY, 140 float toY, int stepCount, long downTime) { 141 float x = fromX; 142 float y = fromY; 143 float yStep = (toY - fromY) / stepCount; 144 float xStep = (toX - fromX) / stepCount; 145 for (int i = 0; i < stepCount; ++i) { 146 y += yStep; 147 x += xStep; 148 sendAction(instrumentation, MotionEvent.ACTION_MOVE, downTime, x, y); 149 } 150 } 151 152 /** 153 * Finishes (synchronously) a drag / move at the specified coordinate. 154 * Normally preceeded by dragStart() and dragTo(). 155 * 156 * @param instrumentation Instrumentation object used by the test. 157 * @param x The x location. 158 * @param y The y location. 159 * @param downTime The initial time of the drag, in ms. 160 */ 161 public static void dragEnd(Instrumentation instrumentation, float x, float y, long downTime) { 162 sendAction(instrumentation, MotionEvent.ACTION_UP, downTime, x, y); 163 } 164 165 /** 166 * Performs a drag between the given coordinates, specified relative to the given view. 167 * This method makes calls to dragStart, dragTo and dragEnd. 168 * 169 * @param instrumentation Instrumentation object used by the test. 170 * @param view The view the coordinates are relative to. 171 * @param fromX The relative x-coordinate of the start point of the drag. 172 * @param toX The relative x-coordinate of the end point of the drag. 173 * @param fromY The relative y-coordinate of the start point of the drag. 174 * @param toY The relative y-coordinate of the end point of the drag. 175 * @param stepCount The total number of motion events that should be generated during the drag. 176 */ 177 public static void dragCompleteView(Instrumentation instrumentation, View view, 178 int fromX, int toX, int fromY, int toY, int stepCount) { 179 int fromLocation[] = getAbsoluteLocationFromRelative(view, fromX, fromY); 180 int toLocation[] = getAbsoluteLocationFromRelative(view, toX, toY); 181 long downTime = dragStart(instrumentation, fromLocation[0], fromLocation[1]); 182 dragTo(instrumentation, fromLocation[0], toLocation[0], fromLocation[1], toLocation[1], 183 stepCount, downTime); 184 dragEnd(instrumentation, toLocation[0], toLocation[1], downTime); 185 } 186 187 /** 188 * Calls performClick on a View on the main UI thread. 189 * 190 * @param instrumentation Instrumentation object used by the test. 191 * @param v The view to call performClick on. 192 */ 193 public static void performClickOnMainSync(Instrumentation instrumentation, final View v) { 194 instrumentation.runOnMainSync(new Runnable() { 195 @Override 196 public void run() { 197 v.performClick(); 198 } 199 }); 200 } 201 202 /** 203 * Clicks on specified view in the given {@link Activity}. 204 * 205 * @param test The test case using this utility. 206 * @param activity Activity containing the view. 207 * @param id The view to be clicked. 208 * @return {@code true} if a view with the given id exists. 209 */ 210 public static boolean clickById(InstrumentationTestCase test, Activity activity, int id) { 211 View v = activity.findViewById(id); 212 if (v == null) return false; 213 clickView(test, v); 214 return true; 215 } 216} 217