Merge changes from topics "presubmit-am-80b91e5f6c3340c785b1772da3a86806", "presubmit-am-8e48e4d2f9da4d69bc62fe6a4b39ef56", "presubmit-am-c978438eb5db452d8793cafc3024df96", "presubmit-am-d09990e2eb2246b1ac4d9766ce468226" into sc-v2-dev

* changes:
  Cleanup in EmulatorClipboardMonitor (1)
  Add wrappers around IO functions to check the return values
  Set host's clipboard in a separate thread
  Log emulator's clipboard access to logcat
This commit is contained in:
TreeHugger Robot
2022-05-13 05:35:34 +00:00
committed by Android (Google) Code Review

View File

@@ -18,12 +18,14 @@ package com.android.server.clipboard;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.ClipData; import android.content.ClipData;
import android.os.SystemProperties;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
import android.system.OsConstants; import android.system.OsConstants;
import android.system.VmSocketAddress; import android.system.VmSocketAddress;
import android.util.Slog; import android.util.Slog;
import java.io.EOFException;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.net.SocketException; import java.net.SocketException;
@@ -39,6 +41,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
private static final String PIPE_NAME = "pipe:clipboard"; private static final String PIPE_NAME = "pipe:clipboard";
private static final int HOST_PORT = 5000; private static final int HOST_PORT = 5000;
private final Thread mHostMonitorThread; private final Thread mHostMonitorThread;
private static final boolean LOG_CLIBOARD_ACCESS =
SystemProperties.getBoolean("ro.boot.qemu.log_clipboard_access", false);
private FileDescriptor mPipe = null; private FileDescriptor mPipe = null;
private static byte[] createOpenHandshake() { private static byte[] createOpenHandshake() {
@@ -51,8 +55,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
return bits; return bits;
} }
private boolean isPipeOpened() { private synchronized FileDescriptor getPipeFD() {
return mPipe != null; return mPipe;
} }
private synchronized boolean openPipe() { private synchronized boolean openPipe() {
@@ -67,7 +71,7 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST)); Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST));
final byte[] handshake = createOpenHandshake(); final byte[] handshake = createOpenHandshake();
Os.write(fd, handshake, 0, handshake.length); writeFully(fd, handshake, 0, handshake.length);
mPipe = fd; mPipe = fd;
return true; return true;
} catch (ErrnoException | SocketException | InterruptedIOException e) { } catch (ErrnoException | SocketException | InterruptedIOException e) {
@@ -90,28 +94,30 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
} }
} }
private byte[] receiveMessage() throws ErrnoException, InterruptedIOException { private byte[] receiveMessage() throws ErrnoException, InterruptedIOException, EOFException {
final byte[] lengthBits = new byte[4]; final byte[] lengthBits = new byte[4];
Os.read(mPipe, lengthBits, 0, lengthBits.length); readFully(mPipe, lengthBits, 0, lengthBits.length);
final ByteBuffer bb = ByteBuffer.wrap(lengthBits); final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
bb.order(ByteOrder.LITTLE_ENDIAN); bb.order(ByteOrder.LITTLE_ENDIAN);
final int msgLen = bb.getInt(); final int msgLen = bb.getInt();
final byte[] msg = new byte[msgLen]; final byte[] msg = new byte[msgLen];
Os.read(mPipe, msg, 0, msg.length); readFully(mPipe, msg, 0, msg.length);
return msg; return msg;
} }
private void sendMessage(final byte[] msg) throws ErrnoException, InterruptedIOException { private static void sendMessage(
final FileDescriptor fd,
final byte[] msg) throws ErrnoException, InterruptedIOException {
final byte[] lengthBits = new byte[4]; final byte[] lengthBits = new byte[4];
final ByteBuffer bb = ByteBuffer.wrap(lengthBits); final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
bb.order(ByteOrder.LITTLE_ENDIAN); bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putInt(msg.length); bb.putInt(msg.length);
Os.write(mPipe, lengthBits, 0, lengthBits.length); writeFully(fd, lengthBits, 0, lengthBits.length);
Os.write(mPipe, msg, 0, msg.length); writeFully(fd, msg, 0, msg.length);
} }
EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) { EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) {
@@ -132,8 +138,11 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
new String[]{"text/plain"}, new String[]{"text/plain"},
new ClipData.Item(str)); new ClipData.Item(str));
if (LOG_CLIBOARD_ACCESS) {
Slog.i(TAG, "Setting the guest clipboard to '" + str + "'");
}
setAndroidClipboard.accept(clip); setAndroidClipboard.accept(clip);
} catch (ErrnoException | InterruptedIOException e) { } catch (ErrnoException | EOFException | InterruptedIOException e) {
closePipe(); closePipe();
} catch (InterruptedException | IllegalArgumentException e) { } catch (InterruptedException | IllegalArgumentException e) {
} }
@@ -156,13 +165,50 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
} }
private void setHostClipboardImpl(final String value) { private void setHostClipboardImpl(final String value) {
try { final FileDescriptor pipeFD = getPipeFD();
if (isPipeOpened()) {
sendMessage(value.getBytes()); if (pipeFD != null) {
Thread t = new Thread(() -> {
if (LOG_CLIBOARD_ACCESS) {
Slog.i(TAG, "Setting the host clipboard to '" + value + "'");
} }
try {
sendMessage(pipeFD, value.getBytes());
} catch (ErrnoException | InterruptedIOException e) { } catch (ErrnoException | InterruptedIOException e) {
Slog.e(TAG, "Failed to set host clipboard " + e.getMessage()); Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} }
});
t.start();
}
}
private static void readFully(final FileDescriptor fd,
final byte[] buf, int offset, int size)
throws ErrnoException, InterruptedIOException, EOFException {
while (size > 0) {
final int r = Os.read(fd, buf, offset, size);
if (r > 0) {
offset += r;
size -= r;
} else {
throw new EOFException();
}
}
}
private static void writeFully(final FileDescriptor fd,
final byte[] buf, int offset, int size)
throws ErrnoException, InterruptedIOException {
while (size > 0) {
final int r = Os.write(fd, buf, offset, size);
if (r > 0) {
offset += r;
size -= r;
} else {
throw new ErrnoException("write", OsConstants.EIO);
}
}
} }
} }