Retrofit vsoc_input_service to use vsock
This allows using vsoc_input_service under qemu without the vsoc/ivshmem
support that is missing in 4.19 gki.
The alternative is to use virtio-input, but in qemu this requires
forwarding a hardware device (by using root permissions) while in crosvm
the same functionality is available through a file descriptor.
Test: launch_cvd -vm_manager=qemu_cli, check adb and vnc
Bug: 143713267
Change-Id: I5b7bdc063ff57aa3a455f77b8a7c23db29e1646e
diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc
index 47cf2e2..5c42e59 100644
--- a/host/commands/run_cvd/launch.cc
+++ b/host/commands/run_cvd/launch.cc
@@ -12,6 +12,8 @@
#include "host/commands/run_cvd/runner_defs.h"
#include "host/commands/run_cvd/pre_launch_initializers.h"
#include "host/commands/run_cvd/vsoc_shared_memory.h"
+#include "host/libs/vm_manager/crosvm_manager.h"
+#include "host/libs/vm_manager/qemu_manager.h"
using cvd::RunnerExitCodes;
using cvd::MonitorEntry;
@@ -246,10 +248,20 @@
GetOnSubprocessExitCallback(config));
}
-cvd::SharedFD CreateVncInputServer(const std::string& path) {
+cvd::SharedFD CreateUnixVncInputServer(const std::string& path) {
auto server = cvd::SharedFD::SocketLocalServer(path.c_str(), false, SOCK_STREAM, 0666);
if (!server->IsOpen()) {
- LOG(ERROR) << "Unable to create mouse server: "
+ LOG(ERROR) << "Unable to create unix input server: "
+ << server->StrError();
+ return cvd::SharedFD();
+ }
+ return server;
+}
+
+cvd::SharedFD CreateVsockVncInputServer(int port) {
+ auto server = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+ if (!server->IsOpen()) {
+ LOG(ERROR) << "Unable to create vsock input server: "
<< server->StrError();
return cvd::SharedFD();
}
@@ -264,33 +276,38 @@
auto port_options = "-port=" + std::to_string(config.vnc_server_port());
cvd::Command vnc_server(config.vnc_server_binary());
vnc_server.AddParameter(port_options);
- if (!config.enable_ivserver()) {
- // When the ivserver is not enabled, the vnc touch_server needs to serve
- // on unix sockets and send input events to whoever connects to it (namely
- // crosvm)
- auto touch_server = CreateVncInputServer(config.touch_socket_path());
- if (!touch_server->IsOpen()) {
- return false;
- }
- vnc_server.AddParameter("-touch_fd=", touch_server);
-
- auto keyboard_server =
- CreateVncInputServer(config.keyboard_socket_path());
- if (!keyboard_server->IsOpen()) {
- return false;
- }
- vnc_server.AddParameter("-keyboard_fd=", keyboard_server);
- // TODO(b/128852363): This should be handled through the wayland mock
- // instead.
- // Additionally it receives the frame updates from a virtual socket
- // instead
- auto frames_server =
- cvd::SharedFD::VsockServer(config.frames_vsock_port(), SOCK_STREAM);
- if (!frames_server->IsOpen()) {
- return false;
- }
- vnc_server.AddParameter("-frame_server_fd=", frames_server);
+ if (config.vm_manager() == vm_manager::QemuManager::name()) {
+ vnc_server.AddParameter("-write_virtio_input");
}
+ // When the ivserver is not enabled, the vnc touch_server needs to serve
+ // on sockets and send input events to whoever connects to it (the VMM).
+ auto touch_server =
+ config.vm_manager() == vm_manager::CrosvmManager::name()
+ ? CreateUnixVncInputServer(config.touch_socket_path())
+ : CreateVsockVncInputServer(config.touch_socket_port());
+ if (!touch_server->IsOpen()) {
+ return false;
+ }
+ vnc_server.AddParameter("-touch_fd=", touch_server);
+
+ auto keyboard_server =
+ config.vm_manager() == vm_manager::CrosvmManager::name()
+ ? CreateUnixVncInputServer(config.keyboard_socket_path())
+ : CreateVsockVncInputServer(config.keyboard_socket_port());
+ if (!keyboard_server->IsOpen()) {
+ return false;
+ }
+ vnc_server.AddParameter("-keyboard_fd=", keyboard_server);
+ // TODO(b/128852363): This should be handled through the wayland mock
+ // instead.
+ // Additionally it receives the frame updates from a virtual socket
+ // instead
+ auto frames_server =
+ cvd::SharedFD::VsockServer(config.frames_vsock_port(), SOCK_STREAM);
+ if (!frames_server->IsOpen()) {
+ return false;
+ }
+ vnc_server.AddParameter("-frame_server_fd=", frames_server);
process_monitor->StartSubprocess(std::move(vnc_server), callback);
return true;
}