mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-07-23 17:31:30 +00:00
feat: update server
This commit is contained in:
parent
1b6a70245d
commit
b6e3ac184d
5 changed files with 567 additions and 23 deletions
|
@ -1,34 +1,13 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
buildscript {
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:3.1.1'
|
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
|
||||||
// in the individual module build.gradle files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.genymobile.scrcpy"
|
applicationId "com.genymobile.scrcpy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 5
|
versionCode 16
|
||||||
versionName "1.12.1"
|
versionName "1.14"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|
114
server/src/test/java/com/genymobile/scrcpy/CodecOptionsTest.java
Normal file
114
server/src/test/java/com/genymobile/scrcpy/CodecOptionsTest.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CodecOptionsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegerImplicit() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("some_key=5");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("some_key", option.getKey());
|
||||||
|
Assert.assertEquals(5, option.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInteger() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("some_key:int=5");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("some_key", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Integer);
|
||||||
|
Assert.assertEquals(5, option.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLong() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("some_key:long=5");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("some_key", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Long);
|
||||||
|
Assert.assertEquals(5L, option.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloat() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("some_key:float=4.5");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("some_key", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Float);
|
||||||
|
Assert.assertEquals(4.5f, option.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testString() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("some_key:string=some_value");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("some_key", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof String);
|
||||||
|
Assert.assertEquals("some_value", option.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringEscaped() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("some_key:string=warning\\,this_is_not=a_new_key");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("some_key", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof String);
|
||||||
|
Assert.assertEquals("warning,this_is_not=a_new_key", option.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testList() {
|
||||||
|
List<CodecOption> codecOptions = CodecOption.parse("a=1,b:int=2,c:long=3,d:float=4.5,e:string=a\\,b=c");
|
||||||
|
|
||||||
|
Assert.assertEquals(5, codecOptions.size());
|
||||||
|
|
||||||
|
CodecOption option;
|
||||||
|
|
||||||
|
option = codecOptions.get(0);
|
||||||
|
Assert.assertEquals("a", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Integer);
|
||||||
|
Assert.assertEquals(1, option.getValue());
|
||||||
|
|
||||||
|
option = codecOptions.get(1);
|
||||||
|
Assert.assertEquals("b", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Integer);
|
||||||
|
Assert.assertEquals(2, option.getValue());
|
||||||
|
|
||||||
|
option = codecOptions.get(2);
|
||||||
|
Assert.assertEquals("c", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Long);
|
||||||
|
Assert.assertEquals(3L, option.getValue());
|
||||||
|
|
||||||
|
option = codecOptions.get(3);
|
||||||
|
Assert.assertEquals("d", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof Float);
|
||||||
|
Assert.assertEquals(4.5f, option.getValue());
|
||||||
|
|
||||||
|
option = codecOptions.get(4);
|
||||||
|
Assert.assertEquals("e", option.getKey());
|
||||||
|
Assert.assertTrue(option.getValue() instanceof String);
|
||||||
|
Assert.assertEquals("a,b=c", option.getValue());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,374 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
|
public class ControlMessageReaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseKeycodeEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
|
||||||
|
dos.writeByte(KeyEvent.ACTION_UP);
|
||||||
|
dos.writeInt(KeyEvent.KEYCODE_ENTER);
|
||||||
|
dos.writeInt(KeyEvent.META_CTRL_ON);
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
// The message type (1 byte) does not count
|
||||||
|
Assert.assertEquals(ControlMessageReader.INJECT_KEYCODE_PAYLOAD_LENGTH, packet.length - 1);
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
|
||||||
|
Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
|
||||||
|
Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode());
|
||||||
|
Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseTextEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_TEXT);
|
||||||
|
byte[] text = "testé".getBytes(StandardCharsets.UTF_8);
|
||||||
|
dos.writeShort(text.length);
|
||||||
|
dos.write(text);
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_TEXT, event.getType());
|
||||||
|
Assert.assertEquals("testé", event.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseLongTextEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_TEXT);
|
||||||
|
byte[] text = new byte[ControlMessageReader.INJECT_TEXT_MAX_LENGTH];
|
||||||
|
Arrays.fill(text, (byte) 'a');
|
||||||
|
dos.writeShort(text.length);
|
||||||
|
dos.write(text);
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_TEXT, event.getType());
|
||||||
|
Assert.assertEquals(new String(text, StandardCharsets.US_ASCII), event.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseTouchEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_TOUCH_EVENT);
|
||||||
|
dos.writeByte(MotionEvent.ACTION_DOWN);
|
||||||
|
dos.writeLong(-42); // pointerId
|
||||||
|
dos.writeInt(100);
|
||||||
|
dos.writeInt(200);
|
||||||
|
dos.writeShort(1080);
|
||||||
|
dos.writeShort(1920);
|
||||||
|
dos.writeShort(0xffff); // pressure
|
||||||
|
dos.writeInt(MotionEvent.BUTTON_PRIMARY);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
// The message type (1 byte) does not count
|
||||||
|
Assert.assertEquals(ControlMessageReader.INJECT_TOUCH_EVENT_PAYLOAD_LENGTH, packet.length - 1);
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_TOUCH_EVENT, event.getType());
|
||||||
|
Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction());
|
||||||
|
Assert.assertEquals(-42, event.getPointerId());
|
||||||
|
Assert.assertEquals(100, event.getPosition().getPoint().getX());
|
||||||
|
Assert.assertEquals(200, event.getPosition().getPoint().getY());
|
||||||
|
Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth());
|
||||||
|
Assert.assertEquals(1920, event.getPosition().getScreenSize().getHeight());
|
||||||
|
Assert.assertEquals(1f, event.getPressure(), 0f); // must be exact
|
||||||
|
Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getButtons());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseScrollEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_SCROLL_EVENT);
|
||||||
|
dos.writeInt(260);
|
||||||
|
dos.writeInt(1026);
|
||||||
|
dos.writeShort(1080);
|
||||||
|
dos.writeShort(1920);
|
||||||
|
dos.writeInt(1);
|
||||||
|
dos.writeInt(-1);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
// The message type (1 byte) does not count
|
||||||
|
Assert.assertEquals(ControlMessageReader.INJECT_SCROLL_EVENT_PAYLOAD_LENGTH, packet.length - 1);
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_SCROLL_EVENT, event.getType());
|
||||||
|
Assert.assertEquals(260, event.getPosition().getPoint().getX());
|
||||||
|
Assert.assertEquals(1026, event.getPosition().getPoint().getY());
|
||||||
|
Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth());
|
||||||
|
Assert.assertEquals(1920, event.getPosition().getScreenSize().getHeight());
|
||||||
|
Assert.assertEquals(1, event.getHScroll());
|
||||||
|
Assert.assertEquals(-1, event.getVScroll());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseBackOrScreenOnEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_BACK_OR_SCREEN_ON);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_BACK_OR_SCREEN_ON, event.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseExpandNotificationPanelEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL, event.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseCollapseNotificationPanelEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL, event.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseGetClipboardEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_GET_CLIPBOARD);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_GET_CLIPBOARD, event.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseSetClipboardEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_SET_CLIPBOARD);
|
||||||
|
dos.writeByte(1); // paste
|
||||||
|
byte[] text = "testé".getBytes(StandardCharsets.UTF_8);
|
||||||
|
dos.writeShort(text.length);
|
||||||
|
dos.write(text);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_SET_CLIPBOARD, event.getType());
|
||||||
|
Assert.assertEquals("testé", event.getText());
|
||||||
|
|
||||||
|
boolean parse = (event.getFlags() & ControlMessage.FLAGS_PASTE) != 0;
|
||||||
|
Assert.assertTrue(parse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseBigSetClipboardEvent() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_SET_CLIPBOARD);
|
||||||
|
|
||||||
|
byte[] rawText = new byte[ControlMessageReader.CLIPBOARD_TEXT_MAX_LENGTH];
|
||||||
|
dos.writeByte(1); // paste
|
||||||
|
Arrays.fill(rawText, (byte) 'a');
|
||||||
|
String text = new String(rawText, 0, rawText.length);
|
||||||
|
|
||||||
|
dos.writeShort(rawText.length);
|
||||||
|
dos.write(rawText);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_SET_CLIPBOARD, event.getType());
|
||||||
|
Assert.assertEquals(text, event.getText());
|
||||||
|
|
||||||
|
boolean parse = (event.getFlags() & ControlMessage.FLAGS_PASTE) != 0;
|
||||||
|
Assert.assertTrue(parse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseSetScreenPowerMode() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_SET_SCREEN_POWER_MODE);
|
||||||
|
dos.writeByte(Device.POWER_MODE_NORMAL);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
// The message type (1 byte) does not count
|
||||||
|
Assert.assertEquals(ControlMessageReader.SET_SCREEN_POWER_MODE_PAYLOAD_LENGTH, packet.length - 1);
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_SET_SCREEN_POWER_MODE, event.getType());
|
||||||
|
Assert.assertEquals(Device.POWER_MODE_NORMAL, event.getAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseRotateDevice() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(ControlMessage.TYPE_ROTATE_DEVICE);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_ROTATE_DEVICE, event.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiEvents() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
|
||||||
|
dos.writeByte(KeyEvent.ACTION_UP);
|
||||||
|
dos.writeInt(KeyEvent.KEYCODE_ENTER);
|
||||||
|
dos.writeInt(KeyEvent.META_CTRL_ON);
|
||||||
|
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
|
||||||
|
dos.writeByte(MotionEvent.ACTION_DOWN);
|
||||||
|
dos.writeInt(MotionEvent.BUTTON_PRIMARY);
|
||||||
|
dos.writeInt(KeyEvent.META_CTRL_ON);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
|
||||||
|
Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
|
||||||
|
Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode());
|
||||||
|
Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
|
||||||
|
|
||||||
|
event = reader.next();
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
|
||||||
|
Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction());
|
||||||
|
Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode());
|
||||||
|
Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPartialEvents() throws IOException {
|
||||||
|
ControlMessageReader reader = new ControlMessageReader();
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
|
||||||
|
dos.writeByte(KeyEvent.ACTION_UP);
|
||||||
|
dos.writeInt(KeyEvent.KEYCODE_ENTER);
|
||||||
|
dos.writeInt(KeyEvent.META_CTRL_ON);
|
||||||
|
|
||||||
|
dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
|
||||||
|
dos.writeByte(MotionEvent.ACTION_DOWN);
|
||||||
|
|
||||||
|
byte[] packet = bos.toByteArray();
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
|
||||||
|
ControlMessage event = reader.next();
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
|
||||||
|
Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
|
||||||
|
Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode());
|
||||||
|
Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
|
||||||
|
|
||||||
|
event = reader.next();
|
||||||
|
Assert.assertNull(event); // the event is not complete
|
||||||
|
|
||||||
|
bos.reset();
|
||||||
|
dos.writeInt(MotionEvent.BUTTON_PRIMARY);
|
||||||
|
dos.writeInt(KeyEvent.META_CTRL_ON);
|
||||||
|
packet = bos.toByteArray();
|
||||||
|
reader.readFrom(new ByteArrayInputStream(packet));
|
||||||
|
|
||||||
|
// the event is now complete
|
||||||
|
event = reader.next();
|
||||||
|
Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
|
||||||
|
Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction());
|
||||||
|
Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode());
|
||||||
|
Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class DeviceMessageWriterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSerializeClipboard() throws IOException {
|
||||||
|
DeviceMessageWriter writer = new DeviceMessageWriter();
|
||||||
|
|
||||||
|
String text = "aéûoç";
|
||||||
|
byte[] data = text.getBytes(StandardCharsets.UTF_8);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(DeviceMessage.TYPE_CLIPBOARD);
|
||||||
|
dos.writeShort(data.length);
|
||||||
|
dos.write(data);
|
||||||
|
|
||||||
|
byte[] expected = bos.toByteArray();
|
||||||
|
|
||||||
|
DeviceMessage msg = DeviceMessage.createClipboard(text);
|
||||||
|
bos = new ByteArrayOutputStream();
|
||||||
|
writer.writeTo(msg, bos);
|
||||||
|
|
||||||
|
byte[] actual = bos.toByteArray();
|
||||||
|
|
||||||
|
Assert.assertArrayEquals(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class StringUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUtf8Truncate() {
|
||||||
|
String s = "aÉbÔc";
|
||||||
|
byte[] utf8 = s.getBytes(StandardCharsets.UTF_8);
|
||||||
|
Assert.assertEquals(7, utf8.length);
|
||||||
|
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 1);
|
||||||
|
Assert.assertEquals(1, count);
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 2);
|
||||||
|
Assert.assertEquals(1, count); // É is 2 bytes-wide
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 3);
|
||||||
|
Assert.assertEquals(3, count);
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 4);
|
||||||
|
Assert.assertEquals(4, count);
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 5);
|
||||||
|
Assert.assertEquals(4, count); // Ô is 2 bytes-wide
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 6);
|
||||||
|
Assert.assertEquals(6, count);
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 7);
|
||||||
|
Assert.assertEquals(7, count);
|
||||||
|
|
||||||
|
count = StringUtils.getUtf8TruncationIndex(utf8, 8);
|
||||||
|
Assert.assertEquals(7, count); // no more chars
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue