Implement plain text clipboard sharing from VM to Android
Bug: 349702327
Test: Run Ferrochrome, copy text in Ferrochrome, and paste text in
Android
Change-Id: I2b5a4050c3994708d71910564deadb610e4163ff
diff --git a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
index a3ecae7..258aeea 100644
--- a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
+++ b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
@@ -17,6 +17,7 @@
package com.android.virtualization.vmlauncher;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.ParcelFileDescriptor.AutoCloseInputStream;
import static android.os.ParcelFileDescriptor.AutoCloseOutputStream;
import static android.system.virtualmachine.VirtualMachineConfig.CPU_TOPOLOGY_MATCH_HOST;
@@ -68,6 +69,7 @@
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -464,10 +466,8 @@
}
private static final int CLIPBOARD_SHARING_SERVER_PORT = 3580;
- // TODO(349702313): Introduce READ_CLIPBOARD_FROM_VM as 0 for reading clipboard from
- // VM.
- // TODO(349702313): Introduce WRITE_CLIPBOARD_TYPE_EMPTY as 1 for receiving empty clipboard data
- // from VM.
+ private static final byte READ_CLIPBOARD_FROM_VM = 0;
+ private static final byte WRITE_CLIPBOARD_TYPE_EMPTY = 1;
private static final byte WRITE_CLIPBOARD_TYPE_TEXT_PLAIN = 2;
private ClipboardManager getClipboardManager() {
@@ -533,6 +533,49 @@
}
}
+ private boolean readClipboardFromVm() {
+ ByteBuffer request = constructClipboardHeader(READ_CLIPBOARD_FROM_VM, 0);
+
+ ParcelFileDescriptor pfd = connectClipboardSharingServer();
+ if (pfd == null) {
+ Log.d(TAG, "file descriptor of ClipboardSharingServer is null");
+ return false;
+ }
+ OutputStream output = new AutoCloseOutputStream(pfd);
+ try {
+ output.write(request.array());
+ output.flush();
+ Log.d(TAG, "successfully send request to the VM for reading clipboard");
+ } catch (IOException e) {
+ Log.e(TAG, "failed to send request to the VM for read clipboard", e);
+ return false;
+ }
+
+ InputStream input = new AutoCloseInputStream(pfd);
+ try {
+ ByteBuffer header = ByteBuffer.wrap(input.readNBytes(8));
+ header.order(ByteOrder.LITTLE_ENDIAN);
+ switch (header.get(0)) {
+ case WRITE_CLIPBOARD_TYPE_EMPTY:
+ Log.d(TAG, "clipboard data in VM is empty");
+ return true;
+ case WRITE_CLIPBOARD_TYPE_TEXT_PLAIN:
+ int dataSize = header.getInt(4);
+ String text_data =
+ new String(input.readNBytes(dataSize), StandardCharsets.UTF_8);
+ getClipboardManager().setPrimaryClip(ClipData.newPlainText(null, text_data));
+ Log.d(TAG, "successfully received clipboard data from VM");
+ return true;
+ default:
+ Log.e(TAG, "unknown clipboard response type");
+ return false;
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "failed to receive clipboard content from the VM", e);
+ return false;
+ }
+ }
+
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
@@ -545,6 +588,9 @@
if (hasFocus) {
Log.d(TAG, "writing clipboard of host device into VM");
writeClipboardToVm();
+ } else {
+ Log.d(TAG, "reading clipboard of VM");
+ readClipboardFromVm();
}
}
}