Merge "Migrate HostClipboardMonitor to virtio-vsock" am: 7265a87552

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1640632

Change-Id: Ia16312f7b9c9b0fa34cdd7e055e88e5ff692656d
This commit is contained in:
Roman Kiryanov
2021-03-31 19:30:07 +00:00
committed by Automerger Merge Worker

View File

@@ -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());
} }