Emulator: handle OOM and Protocol error cases
- OutOfMemoryError can happen naturally if the size of the clipboard is too large to allocate. We should prefer to drop the clipboard data if we have a choice between that and crashing the system server. - OutOfMemoryError can happen unnatturally if the protocol gets out of sync with the host. This can happen quite easily if there is a caught exception and the clipboard monitor tries to keep on trucking, since the protocol doesn't have any built in synchronisation to catch back up to the start of the next message again. The only option to prevent that at the moment is to just close the pipe and reopen it in case of failure to understand something. Bug: 231340598 Test: presubmit Change-Id: Icceb8ec8b3988c32a2eb5f5598a43753460fc26b
This commit is contained in:
committed by
Roman Kiryanov
parent
6192fb8f35
commit
e5b03a179a
@@ -29,6 +29,7 @@ import android.util.Slog;
|
||||
import java.io.EOFException;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -39,12 +40,16 @@ import java.util.function.Consumer;
|
||||
// write contents of the host system's clipboard.
|
||||
class EmulatorClipboardMonitor implements Consumer<ClipData> {
|
||||
private static final String TAG = "EmulatorClipboardMonitor";
|
||||
|
||||
private static final String PIPE_NAME = "pipe:clipboard";
|
||||
private static final int HOST_PORT = 5000;
|
||||
private final Thread mHostMonitorThread;
|
||||
|
||||
private static final boolean LOG_CLIBOARD_ACCESS =
|
||||
SystemProperties.getBoolean("ro.boot.qemu.log_clipboard_access", false);
|
||||
private static final int MAX_CLIPBOARD_BYTES = 128 << 20;
|
||||
|
||||
private FileDescriptor mPipe = null;
|
||||
private final Thread mHostMonitorThread;
|
||||
|
||||
private static byte[] createOpenHandshake() {
|
||||
// String.getBytes doesn't include the null terminator,
|
||||
@@ -97,8 +102,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
|
||||
return fd;
|
||||
}
|
||||
|
||||
private static byte[] receiveMessage(final FileDescriptor fd) throws ErrnoException,
|
||||
InterruptedIOException, EOFException {
|
||||
private byte[] receiveMessage(final FileDescriptor fd) throws ErrnoException,
|
||||
InterruptedIOException, EOFException, ProtocolException {
|
||||
final byte[] lengthBits = new byte[4];
|
||||
readFully(fd, lengthBits, 0, lengthBits.length);
|
||||
|
||||
@@ -106,6 +111,10 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
final int msgLen = bb.getInt();
|
||||
|
||||
if (msgLen <= 0 || msgLen > MAX_CLIPBOARD_BYTES) {
|
||||
throw new ProtocolException("Clipboard message length: " + msgLen + " out of bounds.");
|
||||
}
|
||||
|
||||
final byte[] msg = new byte[msgLen];
|
||||
readFully(fd, msg, 0, msg.length);
|
||||
|
||||
@@ -150,7 +159,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> {
|
||||
}
|
||||
setAndroidClipboard.accept(clip);
|
||||
} catch (ErrnoException | EOFException | InterruptedIOException
|
||||
| InterruptedException e) {
|
||||
| InterruptedException | ProtocolException | OutOfMemoryError e) {
|
||||
Slog.w(TAG, "Failure to read from host clipboard", e);
|
||||
setPipeFD(null);
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user