Merge "Migrate HostClipboardMonitor to virtio-vsock"
This commit is contained in:
@@ -52,6 +52,10 @@ import android.os.SystemProperties;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.system.ErrnoException;
|
||||||
|
import android.system.Os;
|
||||||
|
import android.system.OsConstants;
|
||||||
|
import android.system.VmSocketAddress;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
@@ -63,8 +67,11 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal;
|
|||||||
import com.android.server.uri.UriGrantsManagerInternal;
|
import com.android.server.uri.UriGrantsManagerInternal;
|
||||||
import com.android.server.wm.WindowManagerInternal;
|
import com.android.server.wm.WindowManagerInternal;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.FileDescriptor;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.InterruptedIOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -76,10 +83,10 @@ class HostClipboardMonitor implements Runnable {
|
|||||||
void onHostClipboardUpdated(String contents);
|
void onHostClipboardUpdated(String contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RandomAccessFile mPipe = null;
|
private FileDescriptor mPipe = null;
|
||||||
private HostClipboardCallback mHostClipboardCallback;
|
private HostClipboardCallback mHostClipboardCallback;
|
||||||
private static final String PIPE_NAME = "pipe:clipboard";
|
private static final String PIPE_NAME = "pipe:clipboard";
|
||||||
private static final String PIPE_DEVICE = "/dev/qemu_pipe";
|
private static final int HOST_PORT = 5000;
|
||||||
|
|
||||||
private static byte[] createOpenHandshake() {
|
private static byte[] createOpenHandshake() {
|
||||||
// String.getBytes doesn't include the null terminator,
|
// String.getBytes doesn't include the null terminator,
|
||||||
@@ -93,40 +100,57 @@ class HostClipboardMonitor implements Runnable {
|
|||||||
|
|
||||||
private boolean openPipe() {
|
private boolean openPipe() {
|
||||||
try {
|
try {
|
||||||
final RandomAccessFile pipe = new RandomAccessFile(PIPE_DEVICE, "rw");
|
final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pipe.write(createOpenHandshake());
|
Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST));
|
||||||
mPipe = pipe;
|
|
||||||
|
final byte[] handshake = createOpenHandshake();
|
||||||
|
Os.write(fd, handshake, 0, handshake.length);
|
||||||
|
mPipe = fd;
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException ignore) {
|
} catch (ErrnoException | SocketException | InterruptedIOException e) {
|
||||||
pipe.close();
|
Os.close(fd);
|
||||||
}
|
}
|
||||||
} catch (IOException ignore) {
|
} catch (ErrnoException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closePipe() {
|
private void closePipe() {
|
||||||
try {
|
try {
|
||||||
final RandomAccessFile pipe = mPipe;
|
final FileDescriptor fd = mPipe;
|
||||||
mPipe = null;
|
mPipe = null;
|
||||||
if (pipe != null) {
|
if (fd != null) {
|
||||||
pipe.close();
|
Os.close(fd);
|
||||||
}
|
}
|
||||||
} catch (IOException ignore) {
|
} catch (ErrnoException ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] receiveMessage() throws IOException {
|
private byte[] receiveMessage() throws ErrnoException, InterruptedIOException {
|
||||||
final int size = Integer.reverseBytes(mPipe.readInt());
|
final byte[] lengthBits = new byte[4];
|
||||||
final byte[] receivedData = new byte[size];
|
Os.read(mPipe, lengthBits, 0, lengthBits.length);
|
||||||
mPipe.readFully(receivedData);
|
|
||||||
return receivedData;
|
final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
final int msgLen = bb.getInt();
|
||||||
|
|
||||||
|
final byte[] msg = new byte[msgLen];
|
||||||
|
Os.read(mPipe, msg, 0, msg.length);
|
||||||
|
|
||||||
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(byte[] message) throws IOException {
|
private void sendMessage(byte[] msg) throws ErrnoException, InterruptedIOException {
|
||||||
mPipe.writeInt(Integer.reverseBytes(message.length));
|
final byte[] lengthBits = new byte[4];
|
||||||
mPipe.write(message);
|
final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
bb.putInt(msg.length);
|
||||||
|
|
||||||
|
Os.write(mPipe, lengthBits, 0, lengthBits.length);
|
||||||
|
Os.write(mPipe, msg, 0, msg.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostClipboardMonitor(HostClipboardCallback cb) {
|
public HostClipboardMonitor(HostClipboardCallback cb) {
|
||||||
@@ -135,7 +159,7 @@ class HostClipboardMonitor implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
try {
|
try {
|
||||||
// There's no guarantee that QEMU pipes will be ready at the moment
|
// There's no guarantee that QEMU pipes will be ready at the moment
|
||||||
// this method is invoked. We simply try to get the pipe open and
|
// this method is invoked. We simply try to get the pipe open and
|
||||||
@@ -147,9 +171,10 @@ class HostClipboardMonitor implements Runnable {
|
|||||||
final byte[] receivedData = receiveMessage();
|
final byte[] receivedData = receiveMessage();
|
||||||
mHostClipboardCallback.onHostClipboardUpdated(
|
mHostClipboardCallback.onHostClipboardUpdated(
|
||||||
new String(receivedData));
|
new String(receivedData));
|
||||||
} catch (IOException e) {
|
} catch (ErrnoException | InterruptedIOException e) {
|
||||||
closePipe();
|
closePipe();
|
||||||
} catch (InterruptedException e) {}
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +183,7 @@ class HostClipboardMonitor implements Runnable {
|
|||||||
if (mPipe != null) {
|
if (mPipe != null) {
|
||||||
sendMessage(content.getBytes());
|
sendMessage(content.getBytes());
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch (ErrnoException | InterruptedIOException e) {
|
||||||
Slog.e("HostClipboardMonitor",
|
Slog.e("HostClipboardMonitor",
|
||||||
"Failed to set host clipboard " + e.getMessage());
|
"Failed to set host clipboard " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user