Home | History | Annotate | Download | only in browser
      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.content.browser;
      6 
      7 import android.view.MotionEvent;
      8 import android.view.MotionEvent.PointerCoords;
      9 import android.view.MotionEvent.PointerProperties;
     10 
     11 import org.chromium.base.CalledByNative;
     12 import org.chromium.base.JNINamespace;
     13 
     14 /**
     15  * Provides a Java-side implementation for injecting synthetic touch events.
     16  */
     17 @JNINamespace("content")
     18 public class TouchEventSynthesizer {
     19     private static final int MAX_NUM_POINTERS = 16;
     20 
     21     private static final int ACTION_START = 0;
     22     private static final int ACTION_MOVE = 1;
     23     private static final int ACTION_CANCEL = 2;
     24     private static final int ACTION_END = 3;
     25 
     26     private final ContentViewCore mContentViewCore;
     27     private final PointerProperties[] mPointerProperties;
     28     private final PointerCoords[] mPointerCoords;
     29     private long mDownTimeInMs;
     30 
     31     TouchEventSynthesizer(ContentViewCore contentViewCore) {
     32         mContentViewCore = contentViewCore;
     33         mPointerProperties = new PointerProperties[MAX_NUM_POINTERS];
     34         mPointerCoords = new PointerCoords[MAX_NUM_POINTERS];
     35     }
     36 
     37     @CalledByNative
     38     void setPointer(int index, int x, int y, int id) {
     39         assert (0 <= index && index < MAX_NUM_POINTERS);
     40 
     41         // Convert coordinates from density independent pixels to density dependent pixels.
     42         float scaleFactor = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor();
     43 
     44         PointerCoords coords = new PointerCoords();
     45         coords.x = scaleFactor * x;
     46         coords.y = scaleFactor * y;
     47         coords.pressure = 1.0f;
     48         mPointerCoords[index] = coords;
     49 
     50         PointerProperties properties = new PointerProperties();
     51         properties.id = id;
     52         mPointerProperties[index] = properties;
     53     }
     54 
     55     @CalledByNative
     56     void inject(int action, int pointerCount, long timeInMs) {
     57         switch (action) {
     58             case ACTION_START: {
     59                 mDownTimeInMs = timeInMs;
     60                 MotionEvent event = MotionEvent.obtain(
     61                         mDownTimeInMs, timeInMs, MotionEvent.ACTION_DOWN, 1,
     62                         mPointerProperties, mPointerCoords,
     63                         0, 0, 1, 1, 0, 0, 0, 0);
     64                 mContentViewCore.onTouchEvent(event);
     65                 event.recycle();
     66 
     67                 if (pointerCount > 1) {
     68                     event = MotionEvent.obtain(
     69                             mDownTimeInMs, timeInMs,
     70                             MotionEvent.ACTION_POINTER_DOWN, pointerCount,
     71                             mPointerProperties, mPointerCoords,
     72                             0, 0, 1, 1, 0, 0, 0, 0);
     73                     mContentViewCore.onTouchEvent(event);
     74                     event.recycle();
     75                 }
     76                 break;
     77             }
     78             case ACTION_MOVE: {
     79                 MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
     80                         MotionEvent.ACTION_MOVE,
     81                         pointerCount, mPointerProperties, mPointerCoords,
     82                         0, 0, 1, 1, 0, 0, 0, 0);
     83                 mContentViewCore.onTouchEvent(event);
     84                 event.recycle();
     85                 break;
     86             }
     87             case ACTION_CANCEL: {
     88                 MotionEvent event = MotionEvent.obtain(
     89                         mDownTimeInMs, timeInMs, MotionEvent.ACTION_CANCEL, 1,
     90                         mPointerProperties, mPointerCoords,
     91                         0, 0, 1, 1, 0, 0, 0, 0);
     92                 mContentViewCore.onTouchEvent(event);
     93                 event.recycle();
     94                 break;
     95             }
     96             case ACTION_END: {
     97                 if (pointerCount > 1) {
     98                     MotionEvent event = MotionEvent.obtain(
     99                         mDownTimeInMs, timeInMs, MotionEvent.ACTION_POINTER_UP,
    100                         pointerCount, mPointerProperties, mPointerCoords,
    101                         0, 0, 1, 1, 0, 0, 0, 0);
    102                     mContentViewCore.onTouchEvent(event);
    103                     event.recycle();
    104                 }
    105 
    106                 MotionEvent event = MotionEvent.obtain(
    107                         mDownTimeInMs, timeInMs, MotionEvent.ACTION_UP, 1,
    108                         mPointerProperties, mPointerCoords,
    109                         0, 0, 1, 1, 0, 0, 0, 0);
    110                 mContentViewCore.onTouchEvent(event);
    111                 event.recycle();
    112                 break;
    113             }
    114         }
    115     }
    116 }
    117