mobile/android/base/tests/MotionEventHelper.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 package org.mozilla.gecko.tests;
michael@0 2
michael@0 3 import android.app.Instrumentation;
michael@0 4 import android.os.SystemClock;
michael@0 5 import android.util.FloatMath;
michael@0 6 import android.util.Log;
michael@0 7 import android.view.MotionEvent;
michael@0 8
michael@0 9 class MotionEventHelper {
michael@0 10 private static final String LOGTAG = "RobocopMotionEventHelper";
michael@0 11
michael@0 12 private static final long DRAG_EVENTS_PER_SECOND = 20; // 20 move events per second when doing a drag
michael@0 13
michael@0 14 private final Instrumentation mInstrumentation;
michael@0 15 private final int mSurfaceOffsetX;
michael@0 16 private final int mSurfaceOffsetY;
michael@0 17
michael@0 18 public MotionEventHelper(Instrumentation inst, int surfaceOffsetX, int surfaceOffsetY) {
michael@0 19 mInstrumentation = inst;
michael@0 20 mSurfaceOffsetX = surfaceOffsetX;
michael@0 21 mSurfaceOffsetY = surfaceOffsetY;
michael@0 22 Log.i(LOGTAG, "Initialized using offset (" + mSurfaceOffsetX + "," + mSurfaceOffsetY + ")");
michael@0 23 }
michael@0 24
michael@0 25 public long down(float x, float y) {
michael@0 26 Log.d(LOGTAG, "Triggering down at (" + x + "," + y + ")");
michael@0 27 long downTime = SystemClock.uptimeMillis();
michael@0 28 MotionEvent event = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN, mSurfaceOffsetX + x, mSurfaceOffsetY + y, 0);
michael@0 29 try {
michael@0 30 mInstrumentation.sendPointerSync(event);
michael@0 31 } finally {
michael@0 32 event.recycle();
michael@0 33 event = null;
michael@0 34 }
michael@0 35 return downTime;
michael@0 36 }
michael@0 37
michael@0 38 public long move(long downTime, float x, float y) {
michael@0 39 return move(downTime, SystemClock.uptimeMillis(), x, y);
michael@0 40 }
michael@0 41
michael@0 42 public long move(long downTime, long moveTime, float x, float y) {
michael@0 43 Log.d(LOGTAG, "Triggering move to (" + x + "," + y + ")");
michael@0 44 MotionEvent event = MotionEvent.obtain(downTime, moveTime, MotionEvent.ACTION_MOVE, mSurfaceOffsetX + x, mSurfaceOffsetY + y, 0);
michael@0 45 try {
michael@0 46 mInstrumentation.sendPointerSync(event);
michael@0 47 } finally {
michael@0 48 event.recycle();
michael@0 49 event = null;
michael@0 50 }
michael@0 51 return downTime;
michael@0 52 }
michael@0 53
michael@0 54 public long up(long downTime, float x, float y) {
michael@0 55 return up(downTime, SystemClock.uptimeMillis(), x, y);
michael@0 56 }
michael@0 57
michael@0 58 public long up(long downTime, long upTime, float x, float y) {
michael@0 59 Log.d(LOGTAG, "Triggering up at (" + x + "," + y + ")");
michael@0 60 MotionEvent event = MotionEvent.obtain(downTime, upTime, MotionEvent.ACTION_UP, mSurfaceOffsetX + x, mSurfaceOffsetY + y, 0);
michael@0 61 try {
michael@0 62 mInstrumentation.sendPointerSync(event);
michael@0 63 } finally {
michael@0 64 event.recycle();
michael@0 65 event = null;
michael@0 66 }
michael@0 67 return -1L;
michael@0 68 }
michael@0 69
michael@0 70 public Thread dragAsync(final float startX, final float startY, final float endX, final float endY, final long durationMillis) {
michael@0 71 Thread t = new Thread() {
michael@0 72 @Override
michael@0 73 public void run() {
michael@0 74 int numEvents = (int)(durationMillis * DRAG_EVENTS_PER_SECOND / 1000);
michael@0 75 float eventDx = (endX - startX) / numEvents;
michael@0 76 float eventDy = (endY - startY) / numEvents;
michael@0 77 long downTime = down(startX, startY);
michael@0 78 for (int i = 0; i < numEvents - 1; i++) {
michael@0 79 downTime = move(downTime, startX + (eventDx * i), startY + (eventDy * i));
michael@0 80 try {
michael@0 81 Thread.sleep(1000L / DRAG_EVENTS_PER_SECOND);
michael@0 82 } catch (InterruptedException ie) {
michael@0 83 ie.printStackTrace();
michael@0 84 }
michael@0 85 }
michael@0 86 // sleep a bit before sending the last move so that the calculated
michael@0 87 // fling velocity is low and we don't end up doing a fling afterwards.
michael@0 88 try {
michael@0 89 Thread.sleep(1000L);
michael@0 90 } catch (InterruptedException ie) {
michael@0 91 ie.printStackTrace();
michael@0 92 }
michael@0 93 // do the last one using endX/endY directly to avoid rounding errors
michael@0 94 downTime = move(downTime, endX, endY);
michael@0 95 downTime = up(downTime, endX, endY);
michael@0 96 }
michael@0 97 };
michael@0 98 t.start();
michael@0 99 return t;
michael@0 100 }
michael@0 101
michael@0 102 public void dragSync(float startX, float startY, float endX, float endY, long durationMillis) {
michael@0 103 try {
michael@0 104 dragAsync(startX, startY, endX, endY, durationMillis).join();
michael@0 105 mInstrumentation.waitForIdleSync();
michael@0 106 } catch (InterruptedException ie) {
michael@0 107 ie.printStackTrace();
michael@0 108 }
michael@0 109 }
michael@0 110
michael@0 111 public void dragSync(float startX, float startY, float endX, float endY) {
michael@0 112 dragSync(startX, startY, endX, endY, 1000);
michael@0 113 }
michael@0 114
michael@0 115 public Thread flingAsync(final float startX, final float startY, final float endX, final float endY, final float velocity) {
michael@0 116 // note that the first move after the touch-down is used to get over the panning threshold, and
michael@0 117 // is basically cancelled out. this means we need to generate (at least) two move events, with
michael@0 118 // the last move event hitting the target velocity. to do this we just slice the total distance
michael@0 119 // in half, assuming the first half will get us over the panning threshold and the second half
michael@0 120 // will trigger the fling.
michael@0 121 final float dx = (endX - startX) / 2;
michael@0 122 final float dy = (endY - startY) / 2;
michael@0 123 float distance = FloatMath.sqrt((dx * dx) + (dy * dy));
michael@0 124 final long time = (long)(distance / velocity);
michael@0 125 if (time <= 0) {
michael@0 126 throw new IllegalArgumentException( "Fling parameters require too small a time period" );
michael@0 127 }
michael@0 128 Thread t = new Thread() {
michael@0 129 @Override
michael@0 130 public void run() {
michael@0 131 long downTime = down(startX, startY);
michael@0 132 downTime = move(downTime, downTime + time, startX + dx, startY + dy);
michael@0 133 downTime = move(downTime, downTime + time + time, endX, endY);
michael@0 134 downTime = up(downTime, downTime + time, endX, endY);
michael@0 135 }
michael@0 136 };
michael@0 137 t.start();
michael@0 138 return t;
michael@0 139 }
michael@0 140
michael@0 141 public void flingSync(float startX, float startY, float endX, float endY, float velocity) {
michael@0 142 try {
michael@0 143 flingAsync(startX, startY, endX, endY, velocity).join();
michael@0 144 mInstrumentation.waitForIdleSync();
michael@0 145 } catch (InterruptedException ie) {
michael@0 146 ie.printStackTrace();
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 public void tap(float x, float y) {
michael@0 151 long downTime = down(x, y);
michael@0 152 downTime = up(downTime, x, y);
michael@0 153 }
michael@0 154
michael@0 155 public void doubleTap(float x, float y) {
michael@0 156 tap(x, y);
michael@0 157 tap(x, y);
michael@0 158 }
michael@0 159 }

mercurial