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