• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TouchEventSynthesizer(ContentViewCore contentViewCore)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
setPointer(int index, int x, int y, int id)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
inject(int action, int pointerCount, long timeInMs)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