Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/InputInjectorWrapper.java

Issue 2066683003: [Chromoting] Add InputInjector and InputInjectorWrapper for easy unittesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix FindBugs errors Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.chromoting;
6
7 import android.graphics.Point;
8 import android.view.KeyEvent;
9 import android.view.MotionEvent;
10
11 import org.chromium.chromoting.jni.TouchEventData;
12
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Set;
16 import java.util.TreeSet;
17
18 /**
19 * A set of functions to send users' activities, which are represented by Androi d classes, to
20 * remove host machine. This class uses a {@link InputInjector} to do the real i njections. This
21 * class is not thread-safe.
Lambros 2016/06/17 23:00:10 I don't think it's worth documenting that a class
Hzj_jie 2016/06/19 23:41:39 Done.
22 */
23 public final class InputInjectorWrapper {
24 private static final int[] CTRL_ALT_DEL = {
25 KeyEvent.KEYCODE_CTRL_LEFT,
26 KeyEvent.KEYCODE_ALT_LEFT,
27 KeyEvent.KEYCODE_FORWARD_DEL,
28 };
29
30 private final InputInjector mInjector;
31 /** Set of pressed keys for which we've sent TextEvent. */
Lambros 2016/06/17 23:00:09 Blank line before comment.
Hzj_jie 2016/06/19 23:41:38 Done.
32 private final Set<Integer> mPressedTextKeys;
33
34 public InputInjectorWrapper(InputInjector injector) {
35 Preconditions.notNull(injector);
36 mInjector = injector;
37 mPressedTextKeys = new TreeSet<>();
38 }
39
40 public void sendMouseEvent(Point pos, int button, boolean down) {
41 Preconditions.isTrue(button == TouchInputHandler.BUTTON_UNDEFINED
Lambros 2016/06/17 23:00:09 You could consider adding a button enum for this?
Hzj_jie 2016/06/19 23:41:39 I thought we still discourage from using enum in A
42 || button == TouchInputHandler.BUTTON_LEFT
Lambros 2016/06/17 23:00:09 Line-continuation in Java is +8 spaces from previo
Hzj_jie 2016/06/19 23:41:39 Done.
43 || button == TouchInputHandler.BUTTON_MIDDLE
44 || button == TouchInputHandler.BUTTON_RIGHT);
45 mInjector.sendMouseEvent(pos.x, pos.y, button, down);
46 }
47
48 public void sendMouseDown(Point pos, int button) {
49 sendMouseEvent(pos, button, true);
50 }
51
52 public void sendMouseUp(Point pos, int button) {
53 sendMouseEvent(pos, button, false);
54 }
55
56 public void sendMouseClick(Point pos, int button) {
57 sendMouseDown(pos, button);
58 sendMouseUp(pos, button);
59 }
60
61 public void sendCursorMove(Point pos) {
62 sendMouseUp(pos, TouchInputHandler.BUTTON_UNDEFINED);
63 }
64
65 // TODO (zijiehe): This function will be eventually removed after {@link Inp utStrategyInterface}
66 // has been deprecated.
67 public void sendCursorMove(int x, int y) {
68 sendCursorMove(new Point(x, y));
69 }
70
71 public void sendMouseWheelEvent(float distanceX, float distanceY) {
72 mInjector.sendMouseWheelEvent((int) distanceX, (int) distanceY);
73 }
74
75 public void sendReverseMouseWheelEvent(float distanceX, float distanceY) {
76 sendMouseWheelEvent(-distanceX, -distanceY);
77 }
78
79 /**
80 * Extracts the touch point data from a MotionEvent, converts each point int o a marshallable
81 * object and passes the set of points to the JNI layer to be transmitted to the remote host.
82 *
83 * @param event The event to send to the remote host for injection. NOTE: T his object must be
84 * updated to represent the remote machine's coordinate system before calling this
85 * function.
86 */
87 public void sendTouchEvent(MotionEvent event) {
88 int action = event.getActionMasked();
89 TouchEventData.EventType touchEventType = TouchEventData.EventType.fromM askedAction(action);
90 List<TouchEventData> touchEventList = new ArrayList<TouchEventData>();
91
92 if (action == MotionEvent.ACTION_MOVE) {
93 // In order to process all of the events associated with an ACTION_M OVE event, we need
94 // to walk the list of historical events in order and add each event to our list, then
95 // retrieve the current move event data.
96 int pointerCount = event.getPointerCount();
97 int historySize = event.getHistorySize();
98 for (int h = 0; h < historySize; ++h) {
99 for (int p = 0; p < pointerCount; ++p) {
100 touchEventList.add(new TouchEventData(event.getPointerId(p),
101 event.getHistoricalX(p, h), event.getHistoricalY(p, h),
102 event.getHistoricalSize(p, h), event.getHistoricalSi ze(p, h),
103 event.getHistoricalOrientation(p, h),
104 event.getHistoricalPressure(p, h)));
105 }
106 }
107
108 for (int p = 0; p < pointerCount; p++) {
109 touchEventList.add(new TouchEventData(event.getPointerId(p), eve nt.getX(p),
110 event.getY(p), event.getSize(p), event.getSize(p), event .getOrientation(p),
111 event.getPressure(p)));
112 }
113 } else {
114 // For all other events, we only want to grab the current/active poi nter. The event
115 // contains a list of every active pointer but passing all of of the se to the host can
116 // cause confusion on the remote OS side and result in broken touch gestures.
117 int activePointerIndex = event.getActionIndex();
118 touchEventList.add(new TouchEventData(event.getPointerId(activePoint erIndex),
119 event.getX(activePointerIndex), event.getY(activePointerInde x),
120 event.getSize(activePointerIndex), event.getSize(activePoint erIndex),
121 event.getOrientation(activePointerIndex),
122 event.getPressure(activePointerIndex)));
123 }
124
125 if (!touchEventList.isEmpty()) {
126 mInjector.sendTouchEvent(touchEventType, touchEventList.toArray(new TouchEventData[0]));
127 }
128 }
129
130 public boolean sendKeyEvent(KeyEvent event) {
Lambros 2016/06/17 23:00:10 Add some JavaDoc for this. Maybe: Converts the Key
Hzj_jie 2016/06/19 23:41:39 Done.
131 int keyCode = event.getKeyCode();
132 boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN;
133
134 // Events received from software keyboards generate TextEvent in two
135 // cases:
136 // 1. This is an ACTION_MULTIPLE event.
137 // 2. Ctrl, Alt and Meta are not pressed.
138 // This ensures that on-screen keyboard always injects input that
139 // correspond to what user sees on the screen, while physical keyboard
140 // acts as if it is connected to the remote host.
141 if (event.getAction() == KeyEvent.ACTION_MULTIPLE) {
142 mInjector.sendTextEvent(event.getCharacters());
143 return true;
144 }
145
146 // For Enter getUnicodeChar() returns 10 (line feed), but we still
147 // want to send it as KeyEvent.
148 int unicode = keyCode != KeyEvent.KEYCODE_ENTER ? event.getUnicodeChar() : 0;
149
150 boolean no_modifiers = !event.isAltPressed()
151 && !event.isCtrlPressed() && !event.isMetaPressed();
152
153 if (pressed && unicode != 0 && no_modifiers) {
154 mPressedTextKeys.add(keyCode);
155 int[] codePoints = { unicode };
156 mInjector.sendTextEvent(new String(codePoints, 0, 1));
157 return true;
158 }
159
160 if (!pressed && mPressedTextKeys.contains(keyCode)) {
161 mPressedTextKeys.remove(keyCode);
162 return true;
163 }
164
165 switch (keyCode) {
166 // KEYCODE_AT, KEYCODE_POUND, KEYCODE_STAR and KEYCODE_PLUS are
167 // deprecated, but they still need to be here for older devices and
168 // third-party keyboards that may still generate these events. See
169 // https://source.android.com/devices/input/keyboard-devices.html#le gacy-unsupported-keys
170 case KeyEvent.KEYCODE_AT:
171 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
172 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_2, pressed);
173 return true;
174
175 case KeyEvent.KEYCODE_POUND:
176 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
177 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_3, pressed);
178 return true;
179
180 case KeyEvent.KEYCODE_STAR:
181 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
182 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_8, pressed);
183 return true;
184
185 case KeyEvent.KEYCODE_PLUS:
186 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
187 mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed);
188 return true;
189
190 default:
191 // We try to send all other key codes to the host directly.
192 return mInjector.sendKeyEvent(0, keyCode, pressed);
193 }
194 }
195
196 public void sendKeyDown(int keyCode) {
197 mInjector.sendKeyEvent(0, keyCode, true);
198 }
199
200 public void sendKeyUp(int keyCode) {
201 mInjector.sendKeyEvent(0, keyCode, false);
202 }
203
204 public void sendKeysPress(int[] keyCodes) {
Lambros 2016/06/17 23:00:09 Maybe add JavaDoc for this? This is intended for s
Hzj_jie 2016/06/19 23:41:39 Done.
205 if (keyCodes != null && keyCodes.length > 0) {
206 for (int keyCode : keyCodes) {
207 sendKeyDown(keyCode);
208 }
209 for (int keyCode : keyCodes) {
210 sendKeyUp(keyCode);
211 }
212 }
213 }
214
215 public void sendCtrlAltDel() {
216 sendKeysPress(CTRL_ALT_DEL);
217 }
218 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698