1 #include "host/commands/run_cvd/launch.h"
2 
3 #include <sys/stat.h>
4 #include <sys/types.h>
5 
6 #include <android-base/logging.h>
7 
8 #include "common/libs/fs/shared_fd.h"
9 #include "common/libs/utils/files.h"
10 #include "common/libs/utils/size_utils.h"
11 #include "host/commands/run_cvd/pre_launch_initializers.h"
12 #include "host/commands/run_cvd/runner_defs.h"
13 #include "host/libs/vm_manager/crosvm_manager.h"
14 #include "host/libs/vm_manager/qemu_manager.h"
15 
16 using cuttlefish::MonitorEntry;
17 using cuttlefish::RunnerExitCodes;
18 using cuttlefish::vm_manager::QemuManager;
19 
20 namespace {
21 
GetAdbConnectorTcpArg(const cuttlefish::CuttlefishConfig & config)22 std::string GetAdbConnectorTcpArg(const cuttlefish::CuttlefishConfig& config) {
23   auto instance = config.ForDefaultInstance();
24   return std::string{"127.0.0.1:"} + std::to_string(instance.host_port());
25 }
26 
GetAdbConnectorVsockArg(const cuttlefish::CuttlefishConfig & config)27 std::string GetAdbConnectorVsockArg(const cuttlefish::CuttlefishConfig& config) {
28   auto instance = config.ForDefaultInstance();
29   return std::string{"vsock:"} + std::to_string(instance.vsock_guest_cid()) +
30          std::string{":5555"};
31 }
32 
AdbModeEnabled(const cuttlefish::CuttlefishConfig & config,cuttlefish::AdbMode mode)33 bool AdbModeEnabled(const cuttlefish::CuttlefishConfig& config, cuttlefish::AdbMode mode) {
34   return config.adb_mode().count(mode) > 0;
35 }
36 
AdbVsockTunnelEnabled(const cuttlefish::CuttlefishConfig & config)37 bool AdbVsockTunnelEnabled(const cuttlefish::CuttlefishConfig& config) {
38   auto instance = config.ForDefaultInstance();
39   return instance.vsock_guest_cid() > 2 &&
40          AdbModeEnabled(config, cuttlefish::AdbMode::VsockTunnel);
41 }
42 
AdbVsockHalfTunnelEnabled(const cuttlefish::CuttlefishConfig & config)43 bool AdbVsockHalfTunnelEnabled(const cuttlefish::CuttlefishConfig& config) {
44   auto instance = config.ForDefaultInstance();
45   return instance.vsock_guest_cid() > 2 &&
46          AdbModeEnabled(config, cuttlefish::AdbMode::VsockHalfTunnel);
47 }
48 
AdbTcpConnectorEnabled(const cuttlefish::CuttlefishConfig & config)49 bool AdbTcpConnectorEnabled(const cuttlefish::CuttlefishConfig& config) {
50   bool vsock_tunnel = AdbVsockTunnelEnabled(config);
51   bool vsock_half_tunnel = AdbVsockHalfTunnelEnabled(config);
52   return config.run_adb_connector() && (vsock_tunnel || vsock_half_tunnel);
53 }
54 
AdbVsockConnectorEnabled(const cuttlefish::CuttlefishConfig & config)55 bool AdbVsockConnectorEnabled(const cuttlefish::CuttlefishConfig& config) {
56   return config.run_adb_connector() &&
57          AdbModeEnabled(config, cuttlefish::AdbMode::NativeVsock);
58 }
59 
GetOnSubprocessExitCallback(const cuttlefish::CuttlefishConfig & config)60 cuttlefish::OnSocketReadyCb GetOnSubprocessExitCallback(
61     const cuttlefish::CuttlefishConfig& config) {
62   if (config.restart_subprocesses()) {
63     return cuttlefish::ProcessMonitor::RestartOnExitCb;
64   } else {
65     return cuttlefish::ProcessMonitor::DoNotMonitorCb;
66   }
67 }
68 
CreateUnixInputServer(const std::string & path)69 cuttlefish::SharedFD CreateUnixInputServer(const std::string& path) {
70   auto server =
71       cuttlefish::SharedFD::SocketLocalServer(path.c_str(), false, SOCK_STREAM, 0666);
72   if (!server->IsOpen()) {
73     LOG(ERROR) << "Unable to create unix input server: " << server->StrError();
74     return cuttlefish::SharedFD();
75   }
76   return server;
77 }
78 
79 // Creates the frame and input sockets and add the relevant arguments to the vnc
80 // server and webrtc commands
CreateStreamerServers(cuttlefish::Command * cmd,const cuttlefish::CuttlefishConfig & config)81 StreamerLaunchResult CreateStreamerServers(
82     cuttlefish::Command* cmd, const cuttlefish::CuttlefishConfig& config) {
83   StreamerLaunchResult server_ret;
84   cuttlefish::SharedFD touch_server;
85   cuttlefish::SharedFD keyboard_server;
86 
87   auto instance = config.ForDefaultInstance();
88   if (config.vm_manager() == QemuManager::name()) {
89     cmd->AddParameter("-write_virtio_input");
90 
91     touch_server = cuttlefish::SharedFD::VsockServer(instance.touch_server_port(),
92                                               SOCK_STREAM);
93     keyboard_server =
94         cuttlefish::SharedFD::VsockServer(instance.keyboard_server_port(),
95                                    SOCK_STREAM);
96   } else {
97     touch_server = CreateUnixInputServer(instance.touch_socket_path());
98     keyboard_server = CreateUnixInputServer(instance.keyboard_socket_path());
99   }
100   if (!touch_server->IsOpen()) {
101     LOG(ERROR) << "Could not open touch server: " << touch_server->StrError();
102     return {};
103   }
104   cmd->AddParameter("-touch_fd=", touch_server);
105 
106   if (!keyboard_server->IsOpen()) {
107     LOG(ERROR) << "Could not open keyboard server: "
108                << keyboard_server->StrError();
109     return {};
110   }
111   cmd->AddParameter("-keyboard_fd=", keyboard_server);
112 
113   cuttlefish::SharedFD frames_server;
114   if (config.gpu_mode() == cuttlefish::kGpuModeDrmVirgl ||
115       config.gpu_mode() == cuttlefish::kGpuModeGfxStream) {
116     frames_server = CreateUnixInputServer(instance.frames_socket_path());
117   } else {
118     frames_server = cuttlefish::SharedFD::VsockServer(instance.frames_server_port(),
119                                                SOCK_STREAM);
120   }
121   if (!frames_server->IsOpen()) {
122     LOG(ERROR) << "Could not open frames server: " << frames_server->StrError();
123     return {};
124   }
125   cmd->AddParameter("-frame_server_fd=", frames_server);
126   return server_ret;
127 }
128 
129 }  // namespace
130 
LaunchKernelLogMonitor(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor,unsigned int number_of_event_pipes)131 std::vector<cuttlefish::SharedFD> LaunchKernelLogMonitor(
132     const cuttlefish::CuttlefishConfig& config, cuttlefish::ProcessMonitor* process_monitor,
133     unsigned int number_of_event_pipes) {
134   auto instance = config.ForDefaultInstance();
135   auto log_name = instance.kernel_log_pipe_name();
136   if (mkfifo(log_name.c_str(), 0600) != 0) {
137     LOG(ERROR) << "Unable to create named pipe at " << log_name << ": "
138                << strerror(errno);
139     return {};
140   }
141 
142   cuttlefish::SharedFD pipe;
143   // Open the pipe here (from the launcher) to ensure the pipe is not deleted
144   // due to the usage counters in the kernel reaching zero. If this is not done
145   // and the kernel_log_monitor crashes for some reason the VMM may get SIGPIPE.
146   pipe = cuttlefish::SharedFD::Open(log_name.c_str(), O_RDWR);
147   cuttlefish::Command command(config.kernel_log_monitor_binary());
148   command.AddParameter("-log_pipe_fd=", pipe);
149 
150   std::vector<cuttlefish::SharedFD> ret;
151 
152   if (number_of_event_pipes > 0) {
153     auto param_builder = command.GetParameterBuilder();
154     param_builder << "-subscriber_fds=";
155     for (unsigned int i = 0; i < number_of_event_pipes; ++i) {
156       cuttlefish::SharedFD event_pipe_write_end, event_pipe_read_end;
157       if (!cuttlefish::SharedFD::Pipe(&event_pipe_read_end, &event_pipe_write_end)) {
158         LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
159         std::exit(RunnerExitCodes::kPipeIOError);
160       }
161       if (i > 0) {
162         param_builder << ",";
163       }
164       param_builder << event_pipe_write_end;
165       ret.push_back(event_pipe_read_end);
166     }
167     param_builder.Build();
168   }
169 
170   process_monitor->StartSubprocess(std::move(command),
171                                    GetOnSubprocessExitCallback(config));
172 
173   return ret;
174 }
175 
LaunchLogcatReceiver(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)176 void LaunchLogcatReceiver(const cuttlefish::CuttlefishConfig& config,
177                           cuttlefish::ProcessMonitor* process_monitor) {
178   auto instance = config.ForDefaultInstance();
179   auto log_name = instance.logcat_pipe_name();
180   if (mkfifo(log_name.c_str(), 0600) != 0) {
181     LOG(ERROR) << "Unable to create named pipe at " << log_name << ": "
182                << strerror(errno);
183     return;
184   }
185 
186   cuttlefish::SharedFD pipe;
187   // Open the pipe here (from the launcher) to ensure the pipe is not deleted
188   // due to the usage counters in the kernel reaching zero. If this is not done
189   // and the logcat_receiver crashes for some reason the VMM may get SIGPIPE.
190   pipe = cuttlefish::SharedFD::Open(log_name.c_str(), O_RDWR);
191   cuttlefish::Command command(config.logcat_receiver_binary());
192   command.AddParameter("-log_pipe_fd=", pipe);
193 
194   process_monitor->StartSubprocess(std::move(command),
195                                    GetOnSubprocessExitCallback(config));
196   return;
197 }
198 
LaunchConfigServer(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)199 void LaunchConfigServer(const cuttlefish::CuttlefishConfig& config,
200                         cuttlefish::ProcessMonitor* process_monitor) {
201   auto instance = config.ForDefaultInstance();
202   auto port = instance.config_server_port();
203   auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
204   if (!socket->IsOpen()) {
205     LOG(ERROR) << "Unable to create configuration server socket: "
206                << socket->StrError();
207     std::exit(RunnerExitCodes::kConfigServerError);
208   }
209   cuttlefish::Command cmd(config.config_server_binary());
210   cmd.AddParameter("-server_fd=", socket);
211   process_monitor->StartSubprocess(std::move(cmd),
212                                    GetOnSubprocessExitCallback(config));
213   return;
214 }
215 
LaunchTombstoneReceiverIfEnabled(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)216 void LaunchTombstoneReceiverIfEnabled(const cuttlefish::CuttlefishConfig& config,
217                                       cuttlefish::ProcessMonitor* process_monitor) {
218   if (!config.enable_tombstone_receiver()) {
219     return;
220   }
221   auto instance = config.ForDefaultInstance();
222 
223   std::string tombstoneDir = instance.PerInstancePath("tombstones");
224   if (!cuttlefish::DirectoryExists(tombstoneDir.c_str())) {
225     LOG(DEBUG) << "Setting up " << tombstoneDir;
226     if (mkdir(tombstoneDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) <
227         0) {
228       LOG(ERROR) << "Failed to create tombstone directory: " << tombstoneDir
229                  << ". Error: " << errno;
230       exit(RunnerExitCodes::kTombstoneDirCreationError);
231       return;
232     }
233   }
234 
235   auto port = instance.tombstone_receiver_port();
236   auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
237   if (!socket->IsOpen()) {
238     LOG(ERROR) << "Unable to create tombstone server socket: "
239                << socket->StrError();
240     std::exit(RunnerExitCodes::kTombstoneServerError);
241     return;
242   }
243   cuttlefish::Command cmd(config.tombstone_receiver_binary());
244   cmd.AddParameter("-server_fd=", socket);
245   cmd.AddParameter("-tombstone_dir=", tombstoneDir);
246 
247   process_monitor->StartSubprocess(std::move(cmd),
248                                    GetOnSubprocessExitCallback(config));
249   return;
250 }
251 
LaunchVNCServer(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor,std::function<bool (MonitorEntry *)> callback)252 StreamerLaunchResult LaunchVNCServer(
253     const cuttlefish::CuttlefishConfig& config, cuttlefish::ProcessMonitor* process_monitor,
254     std::function<bool(MonitorEntry*)> callback) {
255   auto instance = config.ForDefaultInstance();
256   // Launch the vnc server, don't wait for it to complete
257   auto port_options = "-port=" + std::to_string(instance.vnc_server_port());
258   cuttlefish::Command vnc_server(config.vnc_server_binary());
259   vnc_server.AddParameter(port_options);
260 
261   auto server_ret = CreateStreamerServers(&vnc_server, config);
262 
263   process_monitor->StartSubprocess(std::move(vnc_server), callback);
264   server_ret.launched = true;
265   return server_ret;
266 }
267 
LaunchAdbConnectorIfEnabled(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config,cuttlefish::SharedFD adbd_events_pipe)268 void LaunchAdbConnectorIfEnabled(cuttlefish::ProcessMonitor* process_monitor,
269                                  const cuttlefish::CuttlefishConfig& config,
270                                  cuttlefish::SharedFD adbd_events_pipe) {
271   cuttlefish::Command adb_connector(config.adb_connector_binary());
272   adb_connector.AddParameter("-adbd_events_fd=", adbd_events_pipe);
273   std::set<std::string> addresses;
274 
275   if (AdbTcpConnectorEnabled(config)) {
276     addresses.insert(GetAdbConnectorTcpArg(config));
277   }
278   if (AdbVsockConnectorEnabled(config)) {
279     addresses.insert(GetAdbConnectorVsockArg(config));
280   }
281 
282   if (addresses.size() > 0) {
283     std::string address_arg = "--addresses=";
284     for (auto& arg : addresses) {
285       address_arg += arg + ",";
286     }
287     address_arg.pop_back();
288     adb_connector.AddParameter(address_arg);
289     process_monitor->StartSubprocess(std::move(adb_connector),
290                                      GetOnSubprocessExitCallback(config));
291   }
292 }
293 
LaunchWebRTC(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)294 StreamerLaunchResult LaunchWebRTC(cuttlefish::ProcessMonitor* process_monitor,
295                                   const cuttlefish::CuttlefishConfig& config) {
296   if (config.ForDefaultInstance().start_webrtc_sig_server()) {
297     cuttlefish::Command sig_server(config.sig_server_binary());
298     sig_server.AddParameter("-assets_dir=", config.webrtc_assets_dir());
299     if (!config.webrtc_certs_dir().empty()) {
300       sig_server.AddParameter("-certs_dir=", config.webrtc_certs_dir());
301     }
302     sig_server.AddParameter("-http_server_port=", config.sig_server_port());
303     process_monitor->StartSubprocess(std::move(sig_server),
304                                      GetOnSubprocessExitCallback(config));
305   }
306 
307   // Currently there is no way to ensure the signaling server will already have
308   // bound the socket to the port by the time the webrtc process runs (the
309   // common technique of doing it from the launcher is not possible here as the
310   // server library being used creates its own sockets). However, this issue is
311   // mitigated slightly by doing some retrying and backoff in the webrtc process
312   // when connecting to the websocket, so it shouldn't be an issue most of the
313   // time.
314 
315   cuttlefish::Command webrtc(config.webrtc_binary());
316 
317   auto server_ret = CreateStreamerServers(&webrtc, config);
318 
319   // TODO get from launcher params
320   process_monitor->StartSubprocess(std::move(webrtc),
321                                    GetOnSubprocessExitCallback(config));
322   server_ret.launched = true;
323 
324   return server_ret;
325 }
326 
StopModemSimulator()327 bool StopModemSimulator() {
328   auto config = cuttlefish::CuttlefishConfig::Get();
329   auto instance = config->ForDefaultInstance();
330 
331   std::string monitor_socket_name = "modem_simulator";
332   std::stringstream ss;
333   ss << instance.host_port();
334   monitor_socket_name.append(ss.str());
335   auto monitor_sock = cuttlefish::SharedFD::SocketLocalClient(
336       monitor_socket_name.c_str(), true, SOCK_STREAM);
337   if (!monitor_sock->IsOpen()) {
338     LOG(ERROR) << "The connection to modem simulator is closed";
339     return false;
340   }
341   std::string msg("STOP");
342   if (monitor_sock->Write(msg.data(), msg.size()) < 0) {
343     monitor_sock->Close();
344     LOG(ERROR) << "Failed to send 'STOP' to modem simulator";
345     return false;
346   }
347   char buf[64] = {0};
348   if (monitor_sock->Read(buf, sizeof(buf)) <= 0) {
349     monitor_sock->Close();
350     LOG(ERROR) << "Failed to read message from modem simulator";
351     return false;
352   }
353   if (strcmp(buf, "OK")) {
354     monitor_sock->Close();
355     LOG(ERROR) << "Read '" << buf << "' instead of 'OK' from modem simulator";
356     return false;
357   }
358 
359   return true;
360 }
361 
LaunchModemSimulatorIfEnabled(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)362 void LaunchModemSimulatorIfEnabled(
363     const cuttlefish::CuttlefishConfig& config,
364     cuttlefish::ProcessMonitor* process_monitor) {
365   if (!config.enable_modem_simulator()) {
366     LOG(DEBUG) << "Modem simulator not enabled";
367     return;
368   }
369 
370   int instance_number = config.modem_simulator_instance_number();
371   if (instance_number > 3 /* max value */ || instance_number < 0) {
372     LOG(ERROR)
373         << "Modem simulator instance number should range between 1 and 3";
374     return;
375   }
376 
377   cuttlefish::Command cmd(
378       config.modem_simulator_binary(), [](cuttlefish::Subprocess* proc) {
379         auto stopped = StopModemSimulator();
380         if (stopped) {
381           return true;
382         }
383         LOG(WARNING) << "Failed to stop modem simulator nicely, "
384                      << "attempting to KILL";
385         return KillSubprocess(proc);
386       });
387 
388   auto instance = config.ForDefaultInstance();
389   auto ports = instance.modem_simulator_ports();
390   auto param_builder = cmd.GetParameterBuilder();
391   param_builder << "-server_fds=";
392   for (int i = 0; i < instance_number; ++i) {
393     auto pos = ports.find(',');
394     auto temp = (pos != std::string::npos) ? ports.substr(0, pos - 1) : ports;
395     auto port = std::stoi(temp);
396     ports = ports.substr(pos + 1);
397 
398     auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
399     if (!socket->IsOpen()) {
400       LOG(ERROR) << "Unable to create modem simulator server socket: "
401                  << socket->StrError();
402       std::exit(RunnerExitCodes::kModemSimulatorServerError);
403     }
404     if (i > 0) {
405       param_builder << ",";
406     }
407     param_builder << socket;
408   }
409   param_builder.Build();
410 
411   process_monitor->StartSubprocess(std::move(cmd),
412                                    GetOnSubprocessExitCallback(config));
413 }
414 
LaunchSocketVsockProxyIfEnabled(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)415 void LaunchSocketVsockProxyIfEnabled(cuttlefish::ProcessMonitor* process_monitor,
416                                      const cuttlefish::CuttlefishConfig& config) {
417   auto instance = config.ForDefaultInstance();
418   if (AdbVsockTunnelEnabled(config)) {
419     cuttlefish::Command adb_tunnel(config.socket_vsock_proxy_binary());
420     adb_tunnel.AddParameter("--server=tcp");
421     adb_tunnel.AddParameter("--vsock_port=6520");
422     adb_tunnel.AddParameter(std::string{"--tcp_port="} +
423                             std::to_string(instance.host_port()));
424     adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
425                             std::to_string(instance.vsock_guest_cid()));
426     process_monitor->StartSubprocess(std::move(adb_tunnel),
427                                      GetOnSubprocessExitCallback(config));
428   }
429   if (AdbVsockHalfTunnelEnabled(config)) {
430     cuttlefish::Command adb_tunnel(config.socket_vsock_proxy_binary());
431     adb_tunnel.AddParameter("--server=tcp");
432     adb_tunnel.AddParameter("--vsock_port=5555");
433     adb_tunnel.AddParameter(std::string{"--tcp_port="} +
434                             std::to_string(instance.host_port()));
435     adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
436                             std::to_string(instance.vsock_guest_cid()));
437     process_monitor->StartSubprocess(std::move(adb_tunnel),
438                                      GetOnSubprocessExitCallback(config));
439   }
440 }
441 
LaunchTpmSimulator(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)442 void LaunchTpmSimulator(cuttlefish::ProcessMonitor* process_monitor,
443                    const cuttlefish::CuttlefishConfig& config) {
444   auto instance = config.ForDefaultInstance();
445   auto port = instance.tpm_port();
446   auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
447   cuttlefish::Command tpm_command(
448       cuttlefish::DefaultHostArtifactsPath("bin/tpm_simulator_manager"));
449   tpm_command.AddParameter("-port=", port);
450   process_monitor->StartSubprocess(std::move(tpm_command),
451                                    GetOnSubprocessExitCallback(config));
452 
453   cuttlefish::Command proxy_command(config.socket_vsock_proxy_binary());
454   proxy_command.AddParameter("--server=vsock");
455   proxy_command.AddParameter("--tcp_port=", port);
456   proxy_command.AddParameter("--vsock_port=", port);
457   process_monitor->StartSubprocess(std::move(proxy_command),
458                                    GetOnSubprocessExitCallback(config));
459 }
460 
LaunchMetrics(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)461 void LaunchMetrics(cuttlefish::ProcessMonitor* process_monitor,
462                    const cuttlefish::CuttlefishConfig& config) {
463   cuttlefish::Command metrics(config.metrics_binary());
464 
465   process_monitor->StartSubprocess(std::move(metrics),
466                                    GetOnSubprocessExitCallback(config));
467 }
468 
LaunchTpmPassthrough(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)469 void LaunchTpmPassthrough(cuttlefish::ProcessMonitor* process_monitor,
470                           const cuttlefish::CuttlefishConfig& config) {
471   auto server = cuttlefish::SharedFD::VsockServer(SOCK_STREAM);
472   if (!server->IsOpen()) {
473     LOG(ERROR) << "Unable to create tpm passthrough server: "
474                << server->StrError();
475     std::exit(RunnerExitCodes::kTpmPassthroughError);
476   }
477   cuttlefish::Command tpm_command(
478       cuttlefish::DefaultHostArtifactsPath("bin/vtpm_passthrough"));
479   tpm_command.AddParameter("-server_fd=", server);
480   tpm_command.AddParameter("-device=", config.tpm_device());
481 
482   process_monitor->StartSubprocess(std::move(tpm_command),
483                                    GetOnSubprocessExitCallback(config));
484 }
485 
LaunchTpm(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)486 void LaunchTpm(cuttlefish::ProcessMonitor* process_monitor,
487                const cuttlefish::CuttlefishConfig& config) {
488   if (config.tpm_device() != "") {
489     if (config.tpm_binary() != "") {
490       LOG(WARNING)
491           << "Both -tpm_device and -tpm_binary were set. Using -tpm_device.";
492     }
493     LaunchTpmPassthrough(process_monitor, config);
494   } else if (config.tpm_binary() != "") {
495     LaunchTpmSimulator(process_monitor, config);
496   }
497 }
498 
LaunchSecureEnvironment(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)499 void LaunchSecureEnvironment(cuttlefish::ProcessMonitor* process_monitor,
500                              const cuttlefish::CuttlefishConfig& config) {
501   auto keymaster_port = config.ForDefaultInstance().keymaster_vsock_port();
502   auto keymaster_server =
503       cuttlefish::SharedFD::VsockServer(keymaster_port, SOCK_STREAM);
504   auto gatekeeper_port = config.ForDefaultInstance().gatekeeper_vsock_port();
505   auto gatekeeper_server =
506       cuttlefish::SharedFD::VsockServer(gatekeeper_port, SOCK_STREAM);
507   cuttlefish::Command command(cuttlefish::DefaultHostArtifactsPath("bin/secure_env"));
508   command.AddParameter("-keymaster_fd=", keymaster_server);
509   command.AddParameter("-gatekeeper_fd=", gatekeeper_server);
510   process_monitor->StartSubprocess(std::move(command),
511                                    GetOnSubprocessExitCallback(config));
512 }
513