aboutsummaryrefslogtreecommitdiff
path: root/app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java
diff options
context:
space:
mode:
authorLena <lena@omega>2026-01-01 00:00:00 +0000
committerLena <lena@omega>2026-06-24 22:14:50 +0300
commiteb0c8951196c637e44daf3c0617b131b997d5d2c (patch)
tree2f83b6a41cee745467e53fc401942b82cea286ea /app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java
downloadscrcpy-android-eb0c8951196c637e44daf3c0617b131b997d5d2c.tar.gz
scrcpy-android: mirror an Android device over wireless ADB0.1
Native Java app for Android 12+ that mirrors another Android device over wireless ADB, forwarding video, audio, touch input, and clipboard. Bundles a pinned scrcpy-server.jar and the vendored libadb-android stack. Supports h264/h265/av1 video and raw/opus audio with in-app codec selection. No NDK, no Kotlin. Includes JVM unit tests and a Docker-based emulator e2e rig.
Diffstat (limited to 'app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java')
-rw-r--r--app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java65
1 files changed, 65 insertions, 0 deletions
diff --git a/app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java b/app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java
new file mode 100644
index 0000000..a84e18e
--- /dev/null
+++ b/app/src/test/java/invalid/lena/scrcpy/ControlMessagesTest.java
@@ -0,0 +1,65 @@
+package invalid.lena.scrcpy;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+
+public class ControlMessagesTest {
+
+ @Test
+ public void touchByteLayout() {
+ // ACTION_DOWN=0, single finger, target 1080x2400, x=100, y=200, full pressure
+ byte[] m = ControlMessages.touch(/* action */ 0, /* pointerId */ 0L,
+ /* x */ 100, /* y */ 200, /* tw */ 1080, /* th */ 2400,
+ /* pressure */ 0xffff, /* actionButton */ 0, /* buttons */ 0);
+ assertEquals(ControlMessages.TOUCH_MSG_LEN, m.length);
+ assertEquals(ControlMessages.TYPE_INJECT_TOUCH_EVENT, m[0]);
+ assertEquals(0, m[1]); // action
+ assertEquals(0L, Wire.readBe64(m, 2)); // pointer id
+ assertEquals(100, Wire.readBe32(m, 10)); // x
+ assertEquals(200, Wire.readBe32(m, 14)); // y
+ assertEquals(1080, ((m[18] & 0xff) << 8) | (m[19] & 0xff)); // tw
+ assertEquals(2400, ((m[20] & 0xff) << 8) | (m[21] & 0xff)); // th
+ assertEquals(0xffff, ((m[22] & 0xff) << 8) | (m[23] & 0xff)); // pressure
+ assertEquals(0, Wire.readBe32(m, 24)); // actionButton
+ assertEquals(0, Wire.readBe32(m, 28)); // buttons
+ }
+
+ @Test
+ public void keycodeByteLayout() {
+ // ACTION_DOWN=0, KEYCODE_A=29, repeat=0, metaState=0
+ byte[] m = ControlMessages.keycode(0, 29, 0, 0);
+ assertEquals(ControlMessages.KEY_MSG_LEN, m.length);
+ assertEquals(ControlMessages.TYPE_INJECT_KEYCODE, m[0]);
+ assertEquals(0, m[1]);
+ assertEquals(29, Wire.readBe32(m, 2));
+ assertEquals(0, Wire.readBe32(m, 6));
+ assertEquals(0, Wire.readBe32(m, 10));
+ }
+
+ @Test
+ public void setClipboardWithUtf8Payload() {
+ String text = "héllo 🎉"; // includes a 4-byte surrogate pair
+ byte[] expected = text.getBytes(StandardCharsets.UTF_8);
+ byte[] m = ControlMessages.setClipboard(0xdeadbeefcafeL, /* paste */ true, text);
+ assertEquals(1 + 8 + 1 + 4 + expected.length, m.length);
+ assertEquals(ControlMessages.TYPE_SET_CLIPBOARD, m[0]);
+ assertEquals(0xdeadbeefcafeL, Wire.readBe64(m, 1));
+ assertEquals(1, m[9]); // paste
+ assertEquals(expected.length, Wire.readBe32(m, 10));
+ byte[] tail = new byte[expected.length];
+ System.arraycopy(m, 14, tail, 0, expected.length);
+ assertArrayEquals(expected, tail);
+ }
+
+ @Test
+ public void setClipboardNoPaste() {
+ byte[] m = ControlMessages.setClipboard(0L, false, "");
+ assertEquals(0, m[9]);
+ assertEquals(0, Wire.readBe32(m, 10));
+ assertEquals(14, m.length);
+ }
+}