1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
package invalid.lena.scrcpy;
import java.nio.charset.StandardCharsets;
// Pure-java encoders for scrcpy control messages. Layouts mirror
// com.genymobile.scrcpy.control.ControlMessageReader in the scrcpy
// server source. Extracted from Controller so the wire format can be
// unit-tested without android.* on the classpath.
public final class ControlMessages {
public static final int TYPE_INJECT_KEYCODE = 0;
public static final int TYPE_INJECT_TEXT = 1;
public static final int TYPE_INJECT_TOUCH_EVENT = 2;
public static final int TYPE_BACK_OR_SCREEN_ON = 4;
public static final int TYPE_SET_CLIPBOARD = 9;
// KeyEvent.ACTION_DOWN / ACTION_UP. Mirror the int values rather
// than depend on android.view.KeyEvent so this stays android-free.
public static final int ACTION_DOWN = 0;
public static final int ACTION_UP = 1;
public static final int TOUCH_MSG_LEN = 32; // 1 + 1 + 8 + 4 + 4 + 2 + 2 + 2 + 4 + 4
public static final int KEY_MSG_LEN = 14; // 1 + 1 + 4 + 4 + 4
public static final int BACK_MSG_LEN = 2; // 1 + 1
private ControlMessages() {}
public static byte[] touch(int action, long pointerId,
int x, int y, int targetW, int targetH,
int pressureU16, int actionButton, int buttons) {
byte[] m = new byte[TOUCH_MSG_LEN];
m[0] = TYPE_INJECT_TOUCH_EVENT;
m[1] = (byte) action;
Wire.writeBe64(m, 2, pointerId);
Wire.writeBe32(m, 10, x);
Wire.writeBe32(m, 14, y);
m[18] = (byte)(targetW >>> 8); m[19] = (byte) targetW;
m[20] = (byte)(targetH >>> 8); m[21] = (byte) targetH;
m[22] = (byte)(pressureU16 >>> 8); m[23] = (byte) pressureU16;
Wire.writeBe32(m, 24, actionButton);
Wire.writeBe32(m, 28, buttons);
return m;
}
public static byte[] keycode(int action, int keycode, int repeat, int metaState) {
byte[] m = new byte[KEY_MSG_LEN];
m[0] = TYPE_INJECT_KEYCODE;
m[1] = (byte) action;
Wire.writeBe32(m, 2, keycode);
Wire.writeBe32(m, 6, repeat);
Wire.writeBe32(m, 10, metaState);
return m;
}
// Single button-press event. scrcpy server interprets this as Back
// when the screen is on, or screen-on when it's off. We send a
// DOWN+UP pair to make a tap; this helper builds one byte pair.
public static byte[] backOrScreenOn(int action) {
return new byte[]{(byte) TYPE_BACK_OR_SCREEN_ON, (byte) action};
}
public static byte[] setClipboard(long sequence, boolean paste, String text) {
byte[] data = text.getBytes(StandardCharsets.UTF_8);
byte[] m = new byte[1 + 8 + 1 + 4 + data.length];
m[0] = TYPE_SET_CLIPBOARD;
Wire.writeBe64(m, 1, sequence);
m[9] = (byte)(paste ? 1 : 0);
Wire.writeBe32(m, 10, data.length);
System.arraycopy(data, 0, m, 14, data.length);
return m;
}
}
|