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.

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

mercurial