1 package com.genymobile.scrcpy;
2 
3 import android.view.KeyEvent;
4 import android.view.MotionEvent;
5 
6 import org.junit.Assert;
7 import org.junit.Test;
8 
9 import java.io.ByteArrayInputStream;
10 import java.io.ByteArrayOutputStream;
11 import java.io.DataOutputStream;
12 import java.io.IOException;
13 import java.nio.charset.StandardCharsets;
14 import java.util.Arrays;
15 
16 
17 public class ControlMessageReaderTest {
18 
19     @Test
testParseKeycodeEvent()20     public void testParseKeycodeEvent() throws IOException {
21         ControlMessageReader reader = new ControlMessageReader();
22 
23         ByteArrayOutputStream bos = new ByteArrayOutputStream();
24         DataOutputStream dos = new DataOutputStream(bos);
25         dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
26         dos.writeByte(KeyEvent.ACTION_UP);
27         dos.writeInt(KeyEvent.KEYCODE_ENTER);
28         dos.writeInt(KeyEvent.META_CTRL_ON);
29         byte[] packet = bos.toByteArray();
30 
31         reader.readFrom(new ByteArrayInputStream(packet));
32         ControlMessage event = reader.next();
33 
34         Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
35         Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
36         Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode());
37         Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
38     }
39 
40     @Test
testParseTextEvent()41     public void testParseTextEvent() throws IOException {
42         ControlMessageReader reader = new ControlMessageReader();
43 
44         ByteArrayOutputStream bos = new ByteArrayOutputStream();
45         DataOutputStream dos = new DataOutputStream(bos);
46         dos.writeByte(ControlMessage.TYPE_INJECT_TEXT);
47         byte[] text = "testé".getBytes(StandardCharsets.UTF_8);
48         dos.writeShort(text.length);
49         dos.write(text);
50         byte[] packet = bos.toByteArray();
51 
52         reader.readFrom(new ByteArrayInputStream(packet));
53         ControlMessage event = reader.next();
54 
55         Assert.assertEquals(ControlMessage.TYPE_INJECT_TEXT, event.getType());
56         Assert.assertEquals("testé", event.getText());
57     }
58 
59     @Test
testParseLongTextEvent()60     public void testParseLongTextEvent() throws IOException {
61         ControlMessageReader reader = new ControlMessageReader();
62 
63         ByteArrayOutputStream bos = new ByteArrayOutputStream();
64         DataOutputStream dos = new DataOutputStream(bos);
65         dos.writeByte(ControlMessage.TYPE_INJECT_TEXT);
66         byte[] text = new byte[ControlMessageReader.TEXT_MAX_LENGTH];
67         Arrays.fill(text, (byte) 'a');
68         dos.writeShort(text.length);
69         dos.write(text);
70         byte[] packet = bos.toByteArray();
71 
72         reader.readFrom(new ByteArrayInputStream(packet));
73         ControlMessage event = reader.next();
74 
75         Assert.assertEquals(ControlMessage.TYPE_INJECT_TEXT, event.getType());
76         Assert.assertEquals(new String(text, StandardCharsets.US_ASCII), event.getText());
77     }
78 
79     @Test
testParseMouseEvent()80     public void testParseMouseEvent() throws IOException {
81         ControlMessageReader reader = new ControlMessageReader();
82 
83         ByteArrayOutputStream bos = new ByteArrayOutputStream();
84         DataOutputStream dos = new DataOutputStream(bos);
85         dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
86         dos.writeByte(MotionEvent.ACTION_DOWN);
87         dos.writeInt(MotionEvent.BUTTON_PRIMARY);
88         dos.writeInt(KeyEvent.META_CTRL_ON);
89         byte[] packet = bos.toByteArray();
90 
91         reader.readFrom(new ByteArrayInputStream(packet));
92         ControlMessage event = reader.next();
93 
94         Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
95         Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction());
96         Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode());
97         Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
98     }
99 
100     @Test
101     @SuppressWarnings("checkstyle:MagicNumber")
testParseScrollEvent()102     public void testParseScrollEvent() throws IOException {
103         ControlMessageReader reader = new ControlMessageReader();
104 
105         ByteArrayOutputStream bos = new ByteArrayOutputStream();
106         DataOutputStream dos = new DataOutputStream(bos);
107         dos.writeByte(ControlMessage.TYPE_INJECT_SCROLL_EVENT);
108         dos.writeInt(260);
109         dos.writeInt(1026);
110         dos.writeShort(1080);
111         dos.writeShort(1920);
112         dos.writeInt(1);
113         dos.writeInt(-1);
114 
115         byte[] packet = bos.toByteArray();
116 
117         reader.readFrom(new ByteArrayInputStream(packet));
118         ControlMessage event = reader.next();
119 
120         Assert.assertEquals(ControlMessage.TYPE_INJECT_SCROLL_EVENT, event.getType());
121         Assert.assertEquals(260, event.getPosition().getPoint().getX());
122         Assert.assertEquals(1026, event.getPosition().getPoint().getY());
123         Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth());
124         Assert.assertEquals(1920, event.getPosition().getScreenSize().getHeight());
125         Assert.assertEquals(1, event.getHScroll());
126         Assert.assertEquals(-1, event.getVScroll());
127     }
128 
129     @Test
testParseBackOrScreenOnEvent()130     public void testParseBackOrScreenOnEvent() throws IOException {
131         ControlMessageReader reader = new ControlMessageReader();
132 
133         ByteArrayOutputStream bos = new ByteArrayOutputStream();
134         DataOutputStream dos = new DataOutputStream(bos);
135         dos.writeByte(ControlMessage.TYPE_BACK_OR_SCREEN_ON);
136 
137         byte[] packet = bos.toByteArray();
138 
139         reader.readFrom(new ByteArrayInputStream(packet));
140         ControlMessage event = reader.next();
141 
142         Assert.assertEquals(ControlMessage.TYPE_BACK_OR_SCREEN_ON, event.getType());
143     }
144 
145     @Test
testParseExpandNotificationPanelEvent()146     public void testParseExpandNotificationPanelEvent() throws IOException {
147         ControlMessageReader reader = new ControlMessageReader();
148 
149         ByteArrayOutputStream bos = new ByteArrayOutputStream();
150         DataOutputStream dos = new DataOutputStream(bos);
151         dos.writeByte(ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL);
152 
153         byte[] packet = bos.toByteArray();
154 
155         reader.readFrom(new ByteArrayInputStream(packet));
156         ControlMessage event = reader.next();
157 
158         Assert.assertEquals(ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL, event.getType());
159     }
160 
161     @Test
testParseCollapseNotificationPanelEvent()162     public void testParseCollapseNotificationPanelEvent() throws IOException {
163         ControlMessageReader reader = new ControlMessageReader();
164 
165         ByteArrayOutputStream bos = new ByteArrayOutputStream();
166         DataOutputStream dos = new DataOutputStream(bos);
167         dos.writeByte(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL);
168 
169         byte[] packet = bos.toByteArray();
170 
171         reader.readFrom(new ByteArrayInputStream(packet));
172         ControlMessage event = reader.next();
173 
174         Assert.assertEquals(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL, event.getType());
175     }
176 
177     @Test
testParseGetClipboardEvent()178     public void testParseGetClipboardEvent() throws IOException {
179         ControlMessageReader reader = new ControlMessageReader();
180 
181         ByteArrayOutputStream bos = new ByteArrayOutputStream();
182         DataOutputStream dos = new DataOutputStream(bos);
183         dos.writeByte(ControlMessage.TYPE_GET_CLIPBOARD);
184 
185         byte[] packet = bos.toByteArray();
186 
187         reader.readFrom(new ByteArrayInputStream(packet));
188         ControlMessage event = reader.next();
189 
190         Assert.assertEquals(ControlMessage.TYPE_GET_CLIPBOARD, event.getType());
191     }
192 
193     @Test
testParseSetClipboardEvent()194     public void testParseSetClipboardEvent() throws IOException {
195         ControlMessageReader reader = new ControlMessageReader();
196 
197         ByteArrayOutputStream bos = new ByteArrayOutputStream();
198         DataOutputStream dos = new DataOutputStream(bos);
199         dos.writeByte(ControlMessage.TYPE_SET_CLIPBOARD);
200         byte[] text = "testé".getBytes(StandardCharsets.UTF_8);
201         dos.writeShort(text.length);
202         dos.write(text);
203 
204         byte[] packet = bos.toByteArray();
205 
206         reader.readFrom(new ByteArrayInputStream(packet));
207         ControlMessage event = reader.next();
208 
209         Assert.assertEquals(ControlMessage.TYPE_SET_CLIPBOARD, event.getType());
210         Assert.assertEquals("testé", event.getText());
211     }
212 
213     @Test
testParseSetScreenPowerMode()214     public void testParseSetScreenPowerMode() throws IOException {
215         ControlMessageReader reader = new ControlMessageReader();
216 
217         ByteArrayOutputStream bos = new ByteArrayOutputStream();
218         DataOutputStream dos = new DataOutputStream(bos);
219         dos.writeByte(ControlMessage.TYPE_SET_SCREEN_POWER_MODE);
220         dos.writeByte(Device.POWER_MODE_NORMAL);
221 
222         byte[] packet = bos.toByteArray();
223 
224         reader.readFrom(new ByteArrayInputStream(packet));
225         ControlMessage event = reader.next();
226 
227         Assert.assertEquals(ControlMessage.TYPE_SET_SCREEN_POWER_MODE, event.getType());
228         Assert.assertEquals(Device.POWER_MODE_NORMAL, event.getAction());
229     }
230 
231     @Test
testMultiEvents()232     public void testMultiEvents() throws IOException {
233         ControlMessageReader reader = new ControlMessageReader();
234 
235         ByteArrayOutputStream bos = new ByteArrayOutputStream();
236         DataOutputStream dos = new DataOutputStream(bos);
237 
238         dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
239         dos.writeByte(KeyEvent.ACTION_UP);
240         dos.writeInt(KeyEvent.KEYCODE_ENTER);
241         dos.writeInt(KeyEvent.META_CTRL_ON);
242 
243         dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
244         dos.writeByte(MotionEvent.ACTION_DOWN);
245         dos.writeInt(MotionEvent.BUTTON_PRIMARY);
246         dos.writeInt(KeyEvent.META_CTRL_ON);
247 
248         byte[] packet = bos.toByteArray();
249         reader.readFrom(new ByteArrayInputStream(packet));
250 
251         ControlMessage event = reader.next();
252         Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
253         Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
254         Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode());
255         Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
256 
257         event = reader.next();
258         Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
259         Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction());
260         Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode());
261         Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
262     }
263 
264     @Test
testPartialEvents()265     public void testPartialEvents() throws IOException {
266         ControlMessageReader reader = new ControlMessageReader();
267 
268         ByteArrayOutputStream bos = new ByteArrayOutputStream();
269         DataOutputStream dos = new DataOutputStream(bos);
270 
271         dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
272         dos.writeByte(KeyEvent.ACTION_UP);
273         dos.writeInt(KeyEvent.KEYCODE_ENTER);
274         dos.writeInt(KeyEvent.META_CTRL_ON);
275 
276         dos.writeByte(ControlMessage.TYPE_INJECT_KEYCODE);
277         dos.writeByte(MotionEvent.ACTION_DOWN);
278 
279         byte[] packet = bos.toByteArray();
280         reader.readFrom(new ByteArrayInputStream(packet));
281 
282         ControlMessage event = reader.next();
283         Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
284         Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
285         Assert.assertEquals(KeyEvent.KEYCODE_ENTER, event.getKeycode());
286         Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
287 
288         event = reader.next();
289         Assert.assertNull(event); // the event is not complete
290 
291         bos.reset();
292         dos.writeInt(MotionEvent.BUTTON_PRIMARY);
293         dos.writeInt(KeyEvent.META_CTRL_ON);
294         packet = bos.toByteArray();
295         reader.readFrom(new ByteArrayInputStream(packet));
296 
297         // the event is now complete
298         event = reader.next();
299         Assert.assertEquals(ControlMessage.TYPE_INJECT_KEYCODE, event.getType());
300         Assert.assertEquals(MotionEvent.ACTION_DOWN, event.getAction());
301         Assert.assertEquals(MotionEvent.BUTTON_PRIMARY, event.getKeycode());
302         Assert.assertEquals(KeyEvent.META_CTRL_ON, event.getMetaState());
303     }
304 }
305