Merge "Migrate HostClipboardMonitor to virtio-vsock" am: 7265a87552 am: 31e043b357
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1640632 Change-Id: Ia247ad02cd0448c68a163d9ef5e23d9e3cfc87bd
This commit is contained in:
@@ -52,6 +52,10 @@ import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
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.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
@@ -63,8 +67,11 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal;
|
||||
import com.android.server.uri.UriGrantsManagerInternal;
|
||||
import com.android.server.wm.WindowManagerInternal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -76,10 +83,10 @@ class HostClipboardMonitor implements Runnable {
|
||||
void onHostClipboardUpdated(String contents);
|
||||
}
|
||||
|
||||
private RandomAccessFile mPipe = null;
|
||||
private FileDescriptor mPipe = null;
|
||||
private HostClipboardCallback mHostClipboardCallback;
|
||||
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() {
|
||||
// String.getBytes doesn't include the null terminator,
|
||||
@@ -93,40 +100,57 @@ class HostClipboardMonitor implements Runnable {
|
||||
|
||||
private boolean openPipe() {
|
||||
try {
|
||||
final RandomAccessFile pipe = new RandomAccessFile(PIPE_DEVICE, "rw");
|
||||
final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0);
|
||||
|
||||
try {
|
||||
pipe.write(createOpenHandshake());
|
||||
mPipe = pipe;
|
||||
Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST));
|
||||
|
||||
final byte[] handshake = createOpenHandshake();
|
||||
Os.write(fd, handshake, 0, handshake.length);
|
||||
mPipe = fd;
|
||||
return true;
|
||||
} catch (IOException ignore) {
|
||||
pipe.close();
|
||||
} catch (ErrnoException | SocketException | InterruptedIOException e) {
|
||||
Os.close(fd);
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
} catch (ErrnoException e) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void closePipe() {
|
||||
try {
|
||||
final RandomAccessFile pipe = mPipe;
|
||||
final FileDescriptor fd = mPipe;
|
||||
mPipe = null;
|
||||
if (pipe != null) {
|
||||
pipe.close();
|
||||
if (fd != null) {
|
||||
Os.close(fd);
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
} catch (ErrnoException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] receiveMessage() throws IOException {
|
||||
final int size = Integer.reverseBytes(mPipe.readInt());
|
||||
final byte[] receivedData = new byte[size];
|
||||
mPipe.readFully(receivedData);
|
||||
return receivedData;
|
||||
private byte[] receiveMessage() throws ErrnoException, InterruptedIOException {
|
||||
final byte[] lengthBits = new byte[4];
|
||||
Os.read(mPipe, lengthBits, 0, lengthBits.length);
|
||||
|
||||
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 {
|
||||
mPipe.writeInt(Integer.reverseBytes(message.length));
|
||||
mPipe.write(message);
|
||||
private void sendMessage(byte[] msg) throws ErrnoException, InterruptedIOException {
|
||||
final byte[] lengthBits = new byte[4];
|
||||
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) {
|
||||
@@ -135,7 +159,7 @@ class HostClipboardMonitor implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while(!Thread.interrupted()) {
|
||||
while (!Thread.interrupted()) {
|
||||
try {
|
||||
// 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
|
||||
@@ -147,9 +171,10 @@ class HostClipboardMonitor implements Runnable {
|
||||
final byte[] receivedData = receiveMessage();
|
||||
mHostClipboardCallback.onHostClipboardUpdated(
|
||||
new String(receivedData));
|
||||
} catch (IOException e) {
|
||||
} catch (ErrnoException | InterruptedIOException e) {
|
||||
closePipe();
|
||||
} catch (InterruptedException e) {}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +183,7 @@ class HostClipboardMonitor implements Runnable {
|
||||
if (mPipe != null) {
|
||||
sendMessage(content.getBytes());
|
||||
}
|
||||
} catch(IOException e) {
|
||||
} catch (ErrnoException | InterruptedIOException e) {
|
||||
Slog.e("HostClipboardMonitor",
|
||||
"Failed to set host clipboard " + e.getMessage());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user