TouchEventSynthesizer.java revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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.view.MotionEvent;
8import android.view.MotionEvent.PointerCoords;
9import android.view.MotionEvent.PointerProperties;
10
11import org.chromium.base.CalledByNative;
12import org.chromium.base.JNINamespace;
13
14/**
15 * Provides a Java-side implementation for injecting synthetic touch events.
16 */
17@JNINamespace("content")
18public 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