You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
scrcpy/server/src/main/java/com/genymobile/scrcpy/EventController.java

140 lines
5.0 KiB
Java

package com.genymobile.scrcpy;
import android.os.SystemClock;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import com.genymobile.scrcpy.wrappers.InputManager;
import java.io.IOException;
public class EventController {
private final Device device;
private final InputManager inputManager;
private final DesktopConnection connection;
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
private long lastMouseDown;
private final MotionEvent.PointerProperties[] pointerProperties = { new MotionEvent.PointerProperties() };
private final MotionEvent.PointerCoords[] pointerCoords = { new MotionEvent.PointerCoords() };
public EventController(Device device, DesktopConnection connection) {
this.device = device;
this.connection = connection;
inputManager = device.getInputManager();
initPointer();
}
private void initPointer() {
MotionEvent.PointerProperties props = pointerProperties[0];
props.id = 0;
props.toolType = MotionEvent.TOOL_TYPE_FINGER;
MotionEvent.PointerCoords coords = pointerCoords[0];
coords.orientation = 0;
coords.pressure = 1;
coords.size = 1;
coords.toolMajor = 1;
coords.toolMinor = 1;
coords.touchMajor = 1;
coords.touchMinor = 1;
}
private void setPointerCoords(Point point) {
MotionEvent.PointerCoords coords = pointerCoords[0];
coords.x = point.getX();
coords.y = point.getY();
}
private void setScroll(int hScroll, int vScroll) {
MotionEvent.PointerCoords coords = pointerCoords[0];
coords.setAxisValue(MotionEvent.AXIS_SCROLL, hScroll);
coords.setAxisValue(MotionEvent.AXIS_VSCROLL, vScroll);
}
public void control() throws IOException {
while (handleEvent());
}
private boolean handleEvent() throws IOException {
ControlEvent controlEvent = connection.receiveControlEvent();
if (controlEvent == null) {
return false;
}
switch (controlEvent.getType()) {
case ControlEvent.TYPE_KEYCODE:
injectKeycode(controlEvent.getAction(), controlEvent.getKeycode(), controlEvent.getMetaState());
break;
case ControlEvent.TYPE_TEXT:
injectText(controlEvent.getText());
break;
case ControlEvent.TYPE_MOUSE:
injectMouse(controlEvent.getAction(), controlEvent.getButtons(), controlEvent.getPosition());
break;
case ControlEvent.TYPE_SCROLL:
injectScroll(controlEvent.getPosition(), controlEvent.getHScroll(), controlEvent.getVScroll());
}
return true;
}
private boolean injectKeycode(int action, int keycode, int metaState) {
return injectKeyEvent(action, keycode, 0, metaState);
}
private boolean injectText(String text) {
KeyEvent[] events = charMap.getEvents(text.toCharArray());
if (events == null) {
return false;
}
for (KeyEvent event : events) {
if (!injectEvent(event)) {
return false;
}
}
return true;
}
private boolean injectMouse(int action, int buttons, Position position) {
long now = SystemClock.uptimeMillis();
if (action == MotionEvent.ACTION_DOWN) {
lastMouseDown = now;
}
Point point = device.getPhysicalPoint(position);
if (point == null) {
// ignore event
return false;
}
setPointerCoords(point);
MotionEvent event = MotionEvent.obtain(lastMouseDown, now, action, 1, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
return injectEvent(event);
}
private boolean injectScroll(Position position, int hScroll, int vScroll) {
long now = SystemClock.uptimeMillis();
Point point = device.getPhysicalPoint(position);
if (point == null) {
// ignore event
return false;
}
setPointerCoords(point);
setScroll(hScroll, vScroll);
MotionEvent event = MotionEvent.obtain(lastMouseDown, now, MotionEvent.ACTION_SCROLL, 1, pointerProperties, pointerCoords, 0, 0, 1f, 1f, 0, 0, InputDevice.SOURCE_MOUSE, 0);
return injectEvent(event);
}
private boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState) {
long now = SystemClock.uptimeMillis();
KeyEvent event = new KeyEvent(now, now, action, keyCode, repeat, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
return injectEvent(event);
}
private boolean injectEvent(InputEvent event) {
return inputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
}