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