Add device clipboard set acknowledgement

Add a device message type so that the device could send acknowledgements
for SET_CLIPBOARD requests.

PR #2814 <https://github.com/Genymobile/scrcpy/pull/2814>
This commit is contained in:
Romain Vimont 2021-11-20 12:10:09 +01:00
parent 901d837165
commit 2a0730ee9b
7 changed files with 66 additions and 1 deletions

View file

@ -1,5 +1,6 @@
#include "device_msg.h" #include "device_msg.h"
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -34,6 +35,11 @@ device_msg_deserialize(const unsigned char *buf, size_t len,
msg->clipboard.text = text; msg->clipboard.text = text;
return 5 + clipboard_len; return 5 + clipboard_len;
} }
case DEVICE_MSG_TYPE_ACK_CLIPBOARD: {
uint64_t sequence = buffer_read64be(&buf[1]);
msg->ack_clipboard.sequence = sequence;
return 9;
}
default: default:
LOGW("Unknown device message type: %d", (int) msg->type); LOGW("Unknown device message type: %d", (int) msg->type);
return -1; // error, we cannot recover return -1; // error, we cannot recover

View file

@ -13,6 +13,7 @@
enum device_msg_type { enum device_msg_type {
DEVICE_MSG_TYPE_CLIPBOARD, DEVICE_MSG_TYPE_CLIPBOARD,
DEVICE_MSG_TYPE_ACK_CLIPBOARD,
}; };
struct device_msg { struct device_msg {
@ -21,6 +22,9 @@ struct device_msg {
struct { struct {
char *text; // owned, to be freed by free() char *text; // owned, to be freed by free()
} clipboard; } clipboard;
struct {
uint64_t sequence;
} ack_clipboard;
}; };
}; };

View file

@ -37,6 +37,9 @@ process_msg(struct device_msg *msg) {
SDL_SetClipboardText(msg->clipboard.text); SDL_SetClipboardText(msg->clipboard.text);
break; break;
} }
case DEVICE_MSG_TYPE_ACK_CLIPBOARD:
// TODO
break;
} }
} }

View file

@ -47,11 +47,26 @@ static void test_deserialize_clipboard_big(void) {
device_msg_destroy(&msg); device_msg_destroy(&msg);
} }
static void test_deserialize_ack_set_clipboard(void) {
const unsigned char input[] = {
DEVICE_MSG_TYPE_ACK_CLIPBOARD,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // sequence
};
struct device_msg msg;
ssize_t r = device_msg_deserialize(input, sizeof(input), &msg);
assert(r == 9);
assert(msg.type == DEVICE_MSG_TYPE_ACK_CLIPBOARD);
assert(msg.ack_clipboard.sequence == UINT64_C(0x0102030405060708));
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
(void) argc; (void) argc;
(void) argv; (void) argv;
test_deserialize_clipboard(); test_deserialize_clipboard();
test_deserialize_clipboard_big(); test_deserialize_clipboard_big();
test_deserialize_ack_set_clipboard();
return 0; return 0;
} }

View file

@ -3,9 +3,11 @@ package com.genymobile.scrcpy;
public final class DeviceMessage { public final class DeviceMessage {
public static final int TYPE_CLIPBOARD = 0; public static final int TYPE_CLIPBOARD = 0;
public static final int TYPE_ACK_CLIPBOARD = 1;
private int type; private int type;
private String text; private String text;
private long sequence;
private DeviceMessage() { private DeviceMessage() {
} }
@ -17,6 +19,13 @@ public final class DeviceMessage {
return event; return event;
} }
public static DeviceMessage createAckClipboard(long sequence) {
DeviceMessage event = new DeviceMessage();
event.type = TYPE_ACK_CLIPBOARD;
event.sequence = sequence;
return event;
}
public int getType() { public int getType() {
return type; return type;
} }
@ -24,4 +33,8 @@ public final class DeviceMessage {
public String getText() { public String getText() {
return text; return text;
} }
public long getSequence() {
return sequence;
}
} }

View file

@ -15,7 +15,7 @@ public class DeviceMessageWriter {
public void writeTo(DeviceMessage msg, OutputStream output) throws IOException { public void writeTo(DeviceMessage msg, OutputStream output) throws IOException {
buffer.clear(); buffer.clear();
buffer.put((byte) DeviceMessage.TYPE_CLIPBOARD); buffer.put((byte) msg.getType());
switch (msg.getType()) { switch (msg.getType()) {
case DeviceMessage.TYPE_CLIPBOARD: case DeviceMessage.TYPE_CLIPBOARD:
String text = msg.getText(); String text = msg.getText();
@ -25,6 +25,10 @@ public class DeviceMessageWriter {
buffer.put(raw, 0, len); buffer.put(raw, 0, len);
output.write(rawBuffer, 0, buffer.position()); output.write(rawBuffer, 0, buffer.position());
break; break;
case DeviceMessage.TYPE_ACK_CLIPBOARD:
buffer.putLong(msg.getSequence());
output.write(rawBuffer, 0, buffer.position());
break;
default: default:
Ln.w("Unknown device message: " + msg.getType()); Ln.w("Unknown device message: " + msg.getType());
break; break;

View file

@ -32,4 +32,24 @@ public class DeviceMessageWriterTest {
Assert.assertArrayEquals(expected, actual); Assert.assertArrayEquals(expected, actual);
} }
@Test
public void testSerializeAckSetClipboard() throws IOException {
DeviceMessageWriter writer = new DeviceMessageWriter();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeByte(DeviceMessage.TYPE_ACK_CLIPBOARD);
dos.writeLong(0x0102030405060708L);
byte[] expected = bos.toByteArray();
DeviceMessage msg = DeviceMessage.createAckClipboard(0x0102030405060708L);
bos = new ByteArrayOutputStream();
writer.writeTo(msg, bos);
byte[] actual = bos.toByteArray();
Assert.assertArrayEquals(expected, actual);
}
} }