mirror of
https://github.com/revanced/jadb.git
synced 2025-05-10 11:24:29 +02:00
Merge pull request #88 from janosvitok/AdbProtocolHandler-cleanup
AdbProtocolHandler cleanup
This commit is contained in:
commit
c380a1bcad
@ -37,91 +37,111 @@ class AdbProtocolHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runServer() throws IOException {
|
private void runServer() throws IOException {
|
||||||
DataInput input = new DataInputStream(socket.getInputStream());
|
try (
|
||||||
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
|
DataInputStream input = new DataInputStream(socket.getInputStream());
|
||||||
|
DataOutputStream output = new DataOutputStream(socket.getOutputStream())
|
||||||
while (true) {
|
) {
|
||||||
byte[] buffer = new byte[4];
|
while (processCommand(input, output)) {
|
||||||
input.readFully(buffer);
|
// nothing to do here
|
||||||
String encodedLength = new String(buffer, StandardCharsets.UTF_8);
|
|
||||||
int length = Integer.parseInt(encodedLength, 16);
|
|
||||||
|
|
||||||
buffer = new byte[length];
|
|
||||||
input.readFully(buffer);
|
|
||||||
String command = new String(buffer, StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
responder.onCommand(command);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ("host:version".equals(command)) {
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
send(output, String.format("%04x", responder.getVersion()));
|
|
||||||
} else if ("host:transport-any".equals(command)) {
|
|
||||||
// TODO: Check so that exactly one device is selected.
|
|
||||||
selected = responder.getDevices().get(0);
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
} else if ("host:devices".equals(command)) {
|
|
||||||
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
|
|
||||||
DataOutputStream writer = new DataOutputStream(tmp);
|
|
||||||
for (AdbDeviceResponder d : responder.getDevices()) {
|
|
||||||
writer.writeBytes(d.getSerial() + "\t" + d.getType() + "\n");
|
|
||||||
}
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
send(output, new String(tmp.toByteArray(), StandardCharsets.UTF_8));
|
|
||||||
} else if (command.startsWith("host:transport:")) {
|
|
||||||
String serial = command.substring("host:transport:".length());
|
|
||||||
selected = findDevice(serial);
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
} else if ("sync:".equals(command)) {
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
try {
|
|
||||||
sync(output, input);
|
|
||||||
} catch (JadbException e) { // sync response with a different type of fail message
|
|
||||||
SyncTransport sync = new SyncTransport(output, input);
|
|
||||||
sync.send("FAIL", e.getMessage());
|
|
||||||
}
|
|
||||||
} else if (command.startsWith("shell:")) {
|
|
||||||
String shellCommand = command.substring("shell:".length());
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
shell(shellCommand, output, input);
|
|
||||||
output.close();
|
|
||||||
return;
|
|
||||||
} else if ("host:get-state".equals(command)) {
|
|
||||||
// TODO: Check so that exactly one device is selected.
|
|
||||||
AdbDeviceResponder device = responder.getDevices().get(0);
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
send(output, device.getType());
|
|
||||||
} else if (command.startsWith("host-serial:")) {
|
|
||||||
String[] strs = command.split(":",0);
|
|
||||||
if (strs.length != 3) {
|
|
||||||
throw new ProtocolException("Invalid command: " + command);
|
|
||||||
}
|
|
||||||
|
|
||||||
String serial = strs[1];
|
|
||||||
boolean found = false;
|
|
||||||
output.writeBytes("OKAY");
|
|
||||||
for (AdbDeviceResponder d : responder.getDevices()) {
|
|
||||||
if (d.getSerial().equals(serial)) {
|
|
||||||
send(output, d.getType());
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
send(output, "unknown");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ProtocolException("Unknown command: " + command);
|
|
||||||
}
|
|
||||||
} catch (ProtocolException e) {
|
|
||||||
output.writeBytes("FAIL");
|
|
||||||
send(output, e.getMessage());
|
|
||||||
}
|
}
|
||||||
output.flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean processCommand(DataInput input, DataOutputStream output) throws IOException {
|
||||||
|
String command = readCommand(input);
|
||||||
|
responder.onCommand(command);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ("host:version".equals(command)) {
|
||||||
|
hostVersion(output);
|
||||||
|
} else if ("host:transport-any".equals(command)) {
|
||||||
|
hostTransportAny(output);
|
||||||
|
} else if ("host:devices".equals(command)) {
|
||||||
|
hostDevices(output);
|
||||||
|
} else if (command.startsWith("host:transport:")) {
|
||||||
|
hostTransport(output, command);
|
||||||
|
} else if ("sync:".equals(command)) {
|
||||||
|
sync(output, input);
|
||||||
|
} else if (command.startsWith("shell:")) {
|
||||||
|
shell(input, output, command);
|
||||||
|
return false;
|
||||||
|
} else if ("host:get-state".equals(command)) {
|
||||||
|
hostGetState(output);
|
||||||
|
} else if (command.startsWith("host-serial:")) {
|
||||||
|
hostSerial(output, command);
|
||||||
|
} else {
|
||||||
|
throw new ProtocolException("Unknown command: " + command);
|
||||||
|
}
|
||||||
|
} catch (ProtocolException e) {
|
||||||
|
output.writeBytes("FAIL");
|
||||||
|
send(output, e.getMessage());
|
||||||
|
}
|
||||||
|
output.flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hostSerial(DataOutputStream output, String command) throws IOException {
|
||||||
|
String[] strs = command.split(":",0);
|
||||||
|
if (strs.length != 3) {
|
||||||
|
throw new ProtocolException("Invalid command: " + command);
|
||||||
|
}
|
||||||
|
|
||||||
|
String serial = strs[1];
|
||||||
|
boolean found = false;
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
for (AdbDeviceResponder d : responder.getDevices()) {
|
||||||
|
if (d.getSerial().equals(serial)) {
|
||||||
|
send(output, d.getType());
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
send(output, "unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hostGetState(DataOutputStream output) throws IOException {
|
||||||
|
// TODO: Check so that exactly one device is selected.
|
||||||
|
AdbDeviceResponder device = responder.getDevices().get(0);
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
send(output, device.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shell(DataInput input, DataOutputStream output, String command) throws IOException {
|
||||||
|
String shellCommand = command.substring("shell:".length());
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
shell(shellCommand, output, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hostTransport(DataOutputStream output, String command) throws IOException {
|
||||||
|
String serial = command.substring("host:transport:".length());
|
||||||
|
selected = findDevice(serial);
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hostDevices(DataOutputStream output) throws IOException {
|
||||||
|
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream writer = new DataOutputStream(tmp);
|
||||||
|
for (AdbDeviceResponder d : responder.getDevices()) {
|
||||||
|
writer.writeBytes(d.getSerial() + "\t" + d.getType() + "\n");
|
||||||
|
}
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
send(output, new String(tmp.toByteArray(), StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hostTransportAny(DataOutputStream output) throws IOException {
|
||||||
|
// TODO: Check so that exactly one device is selected.
|
||||||
|
selected = responder.getDevices().get(0);
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hostVersion(DataOutputStream output) throws IOException {
|
||||||
|
output.writeBytes("OKAY");
|
||||||
|
send(output, String.format("%04x", responder.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
private void shell(String command, DataOutputStream stdout, DataInput stdin) throws IOException {
|
private void shell(String command, DataOutputStream stdout, DataInput stdin) throws IOException {
|
||||||
selected.shell(command, stdout, stdin);
|
selected.shell(command, stdout, stdin);
|
||||||
}
|
}
|
||||||
@ -130,37 +150,60 @@ class AdbProtocolHandler implements Runnable {
|
|||||||
return Integer.reverseBytes(input.readInt());
|
return Integer.reverseBytes(input.readInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int readHexInt(DataInput input) throws IOException {
|
||||||
|
return Integer.parseInt(readString(input, 4), 16);
|
||||||
|
}
|
||||||
|
|
||||||
private String readString(DataInput input, int length) throws IOException {
|
private String readString(DataInput input, int length) throws IOException {
|
||||||
byte[] responseBuffer = new byte[length];
|
byte[] responseBuffer = new byte[length];
|
||||||
input.readFully(responseBuffer);
|
input.readFully(responseBuffer);
|
||||||
return new String(responseBuffer, StandardCharsets.UTF_8);
|
return new String(responseBuffer, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sync(DataOutput output, DataInput input) throws IOException, JadbException {
|
private String readCommand(DataInput input) throws IOException {
|
||||||
String id = readString(input, 4);
|
int length = readHexInt(input);
|
||||||
int length = readInt(input);
|
return readString(input, length);
|
||||||
if ("SEND".equals(id)) {
|
}
|
||||||
String remotePath = readString(input, length);
|
|
||||||
int idx = remotePath.lastIndexOf(',');
|
private void sync(DataOutput output, DataInput input) throws IOException {
|
||||||
String path = remotePath;
|
output.writeBytes("OKAY");
|
||||||
int mode = 0666;
|
try {
|
||||||
if (idx > 0) {
|
String id = readString(input, 4);
|
||||||
path = remotePath.substring(0, idx);
|
int length = readInt(input);
|
||||||
mode = Integer.parseInt(remotePath.substring(idx + 1));
|
if ("SEND".equals(id)) {
|
||||||
}
|
syncSend(output, input, length);
|
||||||
SyncTransport transport = new SyncTransport(output, input);
|
} else if ("RECV".equals(id)) {
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
syncRecv(output, input, length);
|
||||||
transport.readChunksTo(buffer);
|
} else throw new JadbException("Unknown sync id " + id);
|
||||||
selected.filePushed(new RemoteFile(path), mode, buffer);
|
} catch (JadbException e) { // sync response with a different type of fail message
|
||||||
transport.sendStatus("OKAY", 0); // 0 = ignored
|
SyncTransport sync = getSyncTransport(output, input);
|
||||||
} else if ("RECV".equals(id)) {
|
sync.send("FAIL", e.getMessage());
|
||||||
String remotePath = readString(input, length);
|
}
|
||||||
SyncTransport transport = new SyncTransport(output, input);
|
}
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
||||||
selected.filePulled(new RemoteFile(remotePath), buffer);
|
private void syncRecv(DataOutput output, DataInput input, int length) throws IOException, JadbException {
|
||||||
transport.sendStream(new ByteArrayInputStream(buffer.toByteArray()));
|
String remotePath = readString(input, length);
|
||||||
transport.sendStatus("DONE", 0); // ignored
|
SyncTransport transport = getSyncTransport(output, input);
|
||||||
} else throw new JadbException("Unknown sync id " + id);
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
selected.filePulled(new RemoteFile(remotePath), buffer);
|
||||||
|
transport.sendStream(new ByteArrayInputStream(buffer.toByteArray()));
|
||||||
|
transport.sendStatus("DONE", 0); // ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncSend(DataOutput output, DataInput input, int length) throws IOException, JadbException {
|
||||||
|
String remotePath = readString(input, length);
|
||||||
|
int idx = remotePath.lastIndexOf(',');
|
||||||
|
String path = remotePath;
|
||||||
|
int mode = 0666;
|
||||||
|
if (idx > 0) {
|
||||||
|
path = remotePath.substring(0, idx);
|
||||||
|
mode = Integer.parseInt(remotePath.substring(idx + 1));
|
||||||
|
}
|
||||||
|
SyncTransport transport = getSyncTransport(output, input);
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
transport.readChunksTo(buffer);
|
||||||
|
selected.filePushed(new RemoteFile(path), mode, buffer);
|
||||||
|
transport.sendStatus("OKAY", 0); // 0 = ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCommandLength(String command) {
|
private String getCommandLength(String command) {
|
||||||
@ -171,4 +214,8 @@ class AdbProtocolHandler implements Runnable {
|
|||||||
writer.writeBytes(getCommandLength(response));
|
writer.writeBytes(getCommandLength(response));
|
||||||
writer.writeBytes(response);
|
writer.writeBytes(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SyncTransport getSyncTransport(DataOutput output, DataInput input) {
|
||||||
|
return new SyncTransport(output, input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user