1// Copyright 2013 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.android_webview.test.util; 6 7import android.os.SystemClock; 8import android.view.MotionEvent; 9import android.view.View; 10 11import java.util.concurrent.CountDownLatch; 12 13/** 14 * A touch utility class that injects the events directly into the view. 15 * TODO(mkosiba): Merge with TestTouchUtils. 16 * 17 * This is similar to TestTouchUtils but injects the events directly into the view class rather 18 * than going through Instrumentation. This is so that we can avoid the INJECT_PERMISSIONS 19 * exception when a modal dialog pops over the test activity. 20 */ 21public class AwTestTouchUtils { 22 private static void sendAction(View view, int action, long downTime, float x, float y) { 23 long eventTime = SystemClock.uptimeMillis(); 24 MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, 0); 25 view.onTouchEvent(event); 26 } 27 28 private static long dragStart(View view, float x, float y) { 29 long downTime = SystemClock.uptimeMillis(); 30 sendAction(view, MotionEvent.ACTION_DOWN, downTime, x, y); 31 return downTime; 32 } 33 34 private static void dragTo(View view, float fromX, float toX, float fromY, 35 float toY, int stepCount, long downTime) { 36 float x = fromX; 37 float y = fromY; 38 float yStep = (toY - fromY) / stepCount; 39 float xStep = (toX - fromX) / stepCount; 40 for (int i = 0; i < stepCount; ++i) { 41 y += yStep; 42 x += xStep; 43 sendAction(view, MotionEvent.ACTION_MOVE, downTime, x, y); 44 } 45 } 46 47 private static void dragEnd(View view, float x, float y, long downTime) { 48 sendAction(view, MotionEvent.ACTION_UP, downTime, x, y); 49 } 50 51 /** 52 * Performs a drag between the given coordinates, specified relative to the given view. 53 * This is safe to call from the instrumentation thread and will invoke the drag 54 * asynchronously. 55 * 56 * @param view The view the coordinates are relative to. 57 * @param fromX The relative x-coordinate of the start point of the drag. 58 * @param toX The relative x-coordinate of the end point of the drag. 59 * @param fromY The relative y-coordinate of the start point of the drag. 60 * @param toY The relative y-coordinate of the end point of the drag. 61 * @param stepCount The total number of motion events that should be generated during the drag. 62 * @param completionLatch The .countDown method is called on this latch once the drag finishes. 63 */ 64 public static void dragCompleteView(final View view, final int fromX, final int toX, 65 final int fromY, final int toY, final int stepCount, 66 final CountDownLatch completionLatch) { 67 view.post(new Runnable() { 68 @Override 69 public void run() { 70 long downTime = dragStart(view, fromX, fromY); 71 dragTo(view, fromX, toX, fromY, toY, stepCount, downTime); 72 dragEnd(view, toX, toY, downTime); 73 if (completionLatch != null) { 74 completionLatch.countDown(); 75 } 76 } 77 }); 78 } 79 80 /** 81 * Performs a single touch on the center of the supplied view. 82 * This is safe to call from the instrumentation thread and will invoke the touch 83 * asynchronously. 84 * 85 * @param view The view the coordinates are relative to. 86 */ 87 public static void simulateTouchCenterOfView(final View view) throws Throwable { 88 view.post(new Runnable() { 89 @Override 90 public void run() { 91 long eventTime = SystemClock.uptimeMillis(); 92 float x = (float) (view.getRight() - view.getLeft()) / 2; 93 float y = (float) (view.getBottom() - view.getTop()) / 2; 94 view.onTouchEvent(MotionEvent.obtain( 95 eventTime, eventTime, MotionEvent.ACTION_DOWN, 96 x, y, 0)); 97 view.onTouchEvent(MotionEvent.obtain( 98 eventTime, eventTime, MotionEvent.ACTION_UP, 99 x, y, 0)); 100 } 101 }); 102 } 103} 104 105