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