diff options
| -rw-r--r-- | services/core/java/com/android/server/clipboard/ClipboardService.java | 77 | 
1 files changed, 51 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 6aec9fcf9a24..72160c203595 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -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());          }  |