diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java index a4084ed332cf0..44822a3f74298 100644 --- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java +++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java @@ -60,11 +60,11 @@ class EmulatorClipboardMonitor implements Consumer { return mPipe; } - private synchronized boolean openPipe() { - if (mPipe != null) { - return true; - } + private synchronized void setPipeFD(final FileDescriptor fd) { + mPipe = fd; + } + private static FileDescriptor openPipeImpl() { try { final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0); @@ -73,15 +73,32 @@ class EmulatorClipboardMonitor implements Consumer { final byte[] handshake = createOpenHandshake(); writeFully(fd, handshake, 0, handshake.length); - mPipe = fd; - return true; + return fd; } catch (ErrnoException | SocketException | InterruptedIOException e) { Os.close(fd); } } catch (ErrnoException e) { } - return false; + return null; + } + + private void openPipe() throws InterruptedException { + FileDescriptor fd = getPipeFD(); + + if (fd == null) { + fd = openPipeImpl(); + + // 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 + // retry on failure indefinitely. + while (fd == null) { + Thread.sleep(100); + fd = openPipeImpl(); + } + } + + setPipeFD(fd); } private synchronized void closePipe() { @@ -125,12 +142,7 @@ class EmulatorClipboardMonitor implements Consumer { this.mHostMonitorThread = new Thread(() -> { 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 - // retry on failure indefinitely. - while (!openPipe()) { - Thread.sleep(100); - } + openPipe(); final byte[] receivedData = receiveMessage();