Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |