1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "host/libs/config/cuttlefish_config.h"
18 
19 #include <algorithm>
20 #include <climits>
21 #include <cstdlib>
22 #include <cstring>
23 #include <fstream>
24 #include <iomanip>
25 #include <iterator>
26 #include <sstream>
27 #include <string>
28 #include <time.h>
29 
30 #include <android-base/strings.h>
31 #include <glog/logging.h>
32 #include <json/json.h>
33 
34 #include "common/libs/utils/environment.h"
35 #include "common/libs/utils/files.h"
36 #include "host/libs/vm_manager/qemu_manager.h"
37 
38 
39 namespace {
40 
InstanceFromEnvironment()41 int InstanceFromEnvironment() {
42   static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE";
43   static constexpr int kDefaultInstance = 1;
44 
45   // CUTTLEFISH_INSTANCE environment variable
46   const char* instance_str = std::getenv(kInstanceEnvironmentVariable);
47   if (!instance_str) {
48     // Try to get it from the user instead
49     instance_str = std::getenv("USER");
50 
51     if (!instance_str || std::strncmp(instance_str, vsoc::kVsocUserPrefix,
52                                       sizeof(vsoc::kVsocUserPrefix) - 1)) {
53       // No user or we don't recognize this user
54       LOG(WARNING) << "No user or non-vsoc user, returning default config";
55       return kDefaultInstance;
56     }
57     instance_str += sizeof(vsoc::kVsocUserPrefix) - 1;
58 
59     // Set the environment variable so that child processes see it
60     setenv(kInstanceEnvironmentVariable, instance_str, 0);
61   }
62 
63   int instance = std::atoi(instance_str);
64   if (instance <= 0) {
65     instance = kDefaultInstance;
66   }
67 
68   return instance;
69 }
70 
71 const char* kInstances = "instances";
72 const char* kAssemblyDir = "assembly_dir";
73 const char* kSerialNumber = "serial_number";
74 const char* kInstanceDir = "instance_dir";
75 const char* kVmManager = "vm_manager";
76 const char* const kGpuMode = "gpu_mode";
77 const char* const kWaylandSocket = "wayland_socket";
78 const char* const kXDisplay = "x_display";
79 const char* kDeviceTitle = "device_title";
80 
81 const char* kCpus = "cpus";
82 const char* kMemoryMb = "memory_mb";
83 const char* kDpi = "dpi";
84 const char* kXRes = "x_res";
85 const char* kYRes = "y_res";
86 const char* kRefreshRateHz = "refresh_rate_hz";
87 
88 const char* kKernelImagePath = "kernel_image_path";
89 const char* kUseUnpackedKernel = "use_unpacked_kernel";
90 const char* kDecompressedKernelImagePath = "decompressed_kernel_image_path";
91 const char* kDecompressKernel = "decompress_kernel";
92 const char* kGdbFlag = "gdb_flag";
93 const char* kRamdiskImagePath = "ramdisk_image_path";
94 const char* kInitramfsPath = "initramfs_path";
95 const char* kFinalRamdiskPath = "final_ramdisk_path";
96 const char* kVendorRamdiskImagePath = "vendor_ramdisk_image_path";
97 
98 const char* kVirtualDiskPaths = "virtual_disk_paths";
99 const char* kDeprecatedBootCompleted = "deprecated_boot_completed";
100 
101 const char* kMobileBridgeName = "mobile_bridge_name";
102 const char* kMobileTapName = "mobile_tap_name";
103 const char* kWifiTapName = "wifi_tap_name";
104 const char* kVsockGuestCid = "vsock_guest_cid";
105 
106 const char* kUuid = "uuid";
107 const char* kCuttlefishEnvPath = "cuttlefish_env_path";
108 
109 const char* kAdbMode = "adb_mode";
110 const char* kHostPort = "host_port";
111 const char* kAdbIPAndPort = "adb_ip_and_port";
112 const char* kSetupWizardMode = "setupwizard_mode";
113 
114 const char* kQemuBinary = "qemu_binary";
115 const char* kCrosvmBinary = "crosvm_binary";
116 const char* kConsoleForwarderBinary = "console_forwarder_binary";
117 const char* kKernelLogMonitorBinary = "kernel_log_monitor_binary";
118 
119 const char* kEnableVncServer = "enable_vnc_server";
120 const char* kVncServerBinary = "vnc_server_binary";
121 const char* kVncServerPort = "vnc_server_port";
122 
123 const char* kEnableWebRTC = "enable_webrtc";
124 const char* kWebRTCBinary = "webrtc_binary";
125 const char* kWebRTCAssetsDir = "webrtc_assets_dir";
126 const char* kWebRTCPublicIP = "webrtc_public_ip";
127 const char* kWebRTCEnableADBWebSocket = "webrtc_enable_adb_websocket";
128 
129 const char* kEnableVehicleHalServer = "enable_vehicle_hal_server";
130 const char* kVehicleHalServerBinary = "vehicle_hal_server_binary";
131 const char* kVehicleHalServerPort = "vehicle_hal_server_port";
132 
133 const char* kRestartSubprocesses = "restart_subprocesses";
134 const char* kRunAdbConnector = "run_adb_connector";
135 const char* kAdbConnectorBinary = "adb_connector_binary";
136 const char* kSocketVsockProxyBinary = "socket_vsock_proxy_binary";
137 
138 const char* kRunAsDaemon = "run_as_daemon";
139 
140 const char* kDataPolicy = "data_policy";
141 const char* kBlankDataImageMb = "blank_data_image_mb";
142 const char* kBlankDataImageFmt = "blank_data_image_fmt";
143 
144 const char* kLogcatMode = "logcat_mode";
145 const char* kLogcatReceiverBinary = "logcat_receiver_binary";
146 const char* kConfigServerBinary = "config_server_binary";
147 
148 const char* kRunTombstoneReceiver = "enable_tombstone_logger";
149 const char* kTombstoneReceiverBinary = "tombstone_receiver_binary";
150 
151 const char* kWebRTCCertsDir = "webrtc_certs_dir";
152 
153 const char* kBootloader = "bootloader";
154 const char* kUseBootloader = "use_bootloader";
155 
156 const char* kBootSlot = "boot_slot";
157 
158 const char* kLoopMaxPart = "loop_max_part";
159 const char* kGuestEnforceSecurity = "guest_enforce_security";
160 const char* kGuestAuditSecurity = "guest_audit_security";
161 const char* kGuestForceNormalBoot = "guest_force_normal_boot";
162 const char* kBootImageKernelCmdline = "boot_image_kernel_cmdline";
163 const char* kExtraKernelCmdline = "extra_kernel_cmdline";
164 
165 const char* kWifiMacAddress = "wifi_mac_address";
166 }  // namespace
167 
168 namespace vsoc {
169 
170 const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
171 const char* const kGpuModeDrmVirgl = "drm_virgl";
172 const char* const kGpuModeGfxStream = "gfxstream";
173 
DefaultEnvironmentPath(const char * environment_key,const char * default_value,const char * subpath)174 std::string DefaultEnvironmentPath(const char* environment_key,
175                                    const char* default_value,
176                                    const char* subpath) {
177   return cvd::StringFromEnv(environment_key, default_value) + "/" + subpath;
178 }
179 
Dictionary()180 Json::Value* CuttlefishConfig::MutableInstanceSpecific::Dictionary() {
181   return &(*config_->dictionary_)[kInstances][id_];
182 }
183 
Dictionary() const184 const Json::Value* CuttlefishConfig::InstanceSpecific::Dictionary() const {
185   return &(*config_->dictionary_)[kInstances][id_];
186 }
187 
assembly_dir() const188 std::string CuttlefishConfig::assembly_dir() const {
189   return (*dictionary_)[kAssemblyDir].asString();
190 }
set_assembly_dir(const std::string & assembly_dir)191 void CuttlefishConfig::set_assembly_dir(const std::string& assembly_dir) {
192   (*dictionary_)[kAssemblyDir] = assembly_dir;
193 }
194 
instance_dir() const195 std::string CuttlefishConfig::InstanceSpecific::instance_dir() const {
196   return (*Dictionary())[kInstanceDir].asString();
197 }
set_instance_dir(const std::string & instance_dir)198 void CuttlefishConfig::MutableInstanceSpecific::set_instance_dir(
199     const std::string& instance_dir) {
200   (*Dictionary())[kInstanceDir] = instance_dir;
201 }
202 
instance_internal_dir() const203 std::string CuttlefishConfig::InstanceSpecific::instance_internal_dir() const {
204   return PerInstancePath(kInternalDirName);
205 }
206 
vm_manager() const207 std::string CuttlefishConfig::vm_manager() const {
208   return (*dictionary_)[kVmManager].asString();
209 }
set_vm_manager(const std::string & name)210 void CuttlefishConfig::set_vm_manager(const std::string& name) {
211   (*dictionary_)[kVmManager] = name;
212 }
213 
gpu_mode() const214 std::string CuttlefishConfig::gpu_mode() const {
215   return (*dictionary_)[kGpuMode].asString();
216 }
set_gpu_mode(const std::string & name)217 void CuttlefishConfig::set_gpu_mode(const std::string& name) {
218   (*dictionary_)[kGpuMode] = name;
219 }
220 
wayland_socket() const221 std::string CuttlefishConfig::wayland_socket() const {
222   // Don't use SetPath here: the path is already fully formed.
223   return (*dictionary_)[kWaylandSocket].asString();
224 }
set_wayland_socket(const std::string & path)225 void CuttlefishConfig::set_wayland_socket(const std::string& path) {
226   (*dictionary_)[kWaylandSocket] = path;
227 }
228 
x_display() const229 std::string CuttlefishConfig::x_display() const {
230   return (*dictionary_)[kXDisplay].asString();
231 }
set_x_display(const std::string & address)232 void CuttlefishConfig::set_x_display(const std::string& address) {
233   (*dictionary_)[kXDisplay] = address;
234 }
235 
serial_number() const236 std::string CuttlefishConfig::InstanceSpecific::serial_number() const {
237   return (*Dictionary())[kSerialNumber].asString();
238 }
set_serial_number(const std::string & serial_number)239 void CuttlefishConfig::MutableInstanceSpecific::set_serial_number(
240     const std::string& serial_number) {
241   (*Dictionary())[kSerialNumber] = serial_number;
242 }
243 
cpus() const244 int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); }
set_cpus(int cpus)245 void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; }
246 
memory_mb() const247 int CuttlefishConfig::memory_mb() const {
248   return (*dictionary_)[kMemoryMb].asInt();
249 }
set_memory_mb(int memory_mb)250 void CuttlefishConfig::set_memory_mb(int memory_mb) {
251   (*dictionary_)[kMemoryMb] = memory_mb;
252 }
253 
dpi() const254 int CuttlefishConfig::dpi() const { return (*dictionary_)[kDpi].asInt(); }
set_dpi(int dpi)255 void CuttlefishConfig::set_dpi(int dpi) { (*dictionary_)[kDpi] = dpi; }
256 
x_res() const257 int CuttlefishConfig::x_res() const { return (*dictionary_)[kXRes].asInt(); }
set_x_res(int x_res)258 void CuttlefishConfig::set_x_res(int x_res) { (*dictionary_)[kXRes] = x_res; }
259 
y_res() const260 int CuttlefishConfig::y_res() const { return (*dictionary_)[kYRes].asInt(); }
set_y_res(int y_res)261 void CuttlefishConfig::set_y_res(int y_res) { (*dictionary_)[kYRes] = y_res; }
262 
refresh_rate_hz() const263 int CuttlefishConfig::refresh_rate_hz() const {
264   return (*dictionary_)[kRefreshRateHz].asInt();
265 }
set_refresh_rate_hz(int refresh_rate_hz)266 void CuttlefishConfig::set_refresh_rate_hz(int refresh_rate_hz) {
267   (*dictionary_)[kRefreshRateHz] = refresh_rate_hz;
268 }
269 
kernel_image_path() const270 std::string CuttlefishConfig::kernel_image_path() const {
271   return (*dictionary_)[kKernelImagePath].asString();
272 }
273 
SetPath(const std::string & key,const std::string & path)274 void CuttlefishConfig::SetPath(const std::string& key,
275                                const std::string& path) {
276   if (!path.empty()) {
277     (*dictionary_)[key] = cvd::AbsolutePath(path);
278   }
279 }
280 
set_kernel_image_path(const std::string & kernel_image_path)281 void CuttlefishConfig::set_kernel_image_path(
282     const std::string& kernel_image_path) {
283   SetPath(kKernelImagePath, kernel_image_path);
284 }
285 
use_unpacked_kernel() const286 bool CuttlefishConfig::use_unpacked_kernel() const {
287   return (*dictionary_)[kUseUnpackedKernel].asBool();
288 }
289 
set_use_unpacked_kernel(bool use_unpacked_kernel)290 void CuttlefishConfig::set_use_unpacked_kernel(bool use_unpacked_kernel) {
291   (*dictionary_)[kUseUnpackedKernel] = use_unpacked_kernel;
292 }
293 
decompress_kernel() const294 bool CuttlefishConfig::decompress_kernel() const {
295   return (*dictionary_)[kDecompressKernel].asBool();
296 }
set_decompress_kernel(bool decompress_kernel)297 void CuttlefishConfig::set_decompress_kernel(bool decompress_kernel) {
298   (*dictionary_)[kDecompressKernel] = decompress_kernel;
299 }
300 
decompressed_kernel_image_path() const301 std::string CuttlefishConfig::decompressed_kernel_image_path() const {
302   return (*dictionary_)[kDecompressedKernelImagePath].asString();
303 }
set_decompressed_kernel_image_path(const std::string & path)304 void CuttlefishConfig::set_decompressed_kernel_image_path(
305     const std::string& path) {
306   SetPath(kDecompressedKernelImagePath, path);
307 }
308 
gdb_flag() const309 std::string CuttlefishConfig::gdb_flag() const {
310   return (*dictionary_)[kGdbFlag].asString();
311 }
312 
set_gdb_flag(const std::string & device)313 void CuttlefishConfig::set_gdb_flag(const std::string& device) {
314   (*dictionary_)[kGdbFlag] = device;
315 }
316 
ramdisk_image_path() const317 std::string CuttlefishConfig::ramdisk_image_path() const {
318   return (*dictionary_)[kRamdiskImagePath].asString();
319 }
set_ramdisk_image_path(const std::string & ramdisk_image_path)320 void CuttlefishConfig::set_ramdisk_image_path(
321     const std::string& ramdisk_image_path) {
322   SetPath(kRamdiskImagePath, ramdisk_image_path);
323 }
324 
initramfs_path() const325 std::string CuttlefishConfig::initramfs_path() const {
326   return (*dictionary_)[kInitramfsPath].asString();
327 }
set_initramfs_path(const std::string & initramfs_path)328 void CuttlefishConfig::set_initramfs_path(const std::string& initramfs_path) {
329   SetPath(kInitramfsPath, initramfs_path);
330 }
331 
final_ramdisk_path() const332 std::string CuttlefishConfig::final_ramdisk_path() const {
333   return (*dictionary_)[kFinalRamdiskPath].asString();
334 }
set_final_ramdisk_path(const std::string & final_ramdisk_path)335 void CuttlefishConfig::set_final_ramdisk_path(
336     const std::string& final_ramdisk_path) {
337   SetPath(kFinalRamdiskPath, final_ramdisk_path);
338 }
339 
vendor_ramdisk_image_path() const340 std::string CuttlefishConfig::vendor_ramdisk_image_path() const {
341   return (*dictionary_)[kVendorRamdiskImagePath].asString();
342 }
set_vendor_ramdisk_image_path(const std::string & vendor_ramdisk_image_path)343 void CuttlefishConfig::set_vendor_ramdisk_image_path(
344     const std::string& vendor_ramdisk_image_path) {
345   SetPath(kVendorRamdiskImagePath, vendor_ramdisk_image_path);
346 }
347 
virtual_disk_paths() const348 std::vector<std::string> CuttlefishConfig::InstanceSpecific::virtual_disk_paths() const {
349   std::vector<std::string> virtual_disks;
350   auto virtual_disks_json_obj = (*Dictionary())[kVirtualDiskPaths];
351   for (const auto& disk : virtual_disks_json_obj) {
352     virtual_disks.push_back(disk.asString());
353   }
354   return virtual_disks;
355 }
set_virtual_disk_paths(const std::vector<std::string> & virtual_disk_paths)356 void CuttlefishConfig::MutableInstanceSpecific::set_virtual_disk_paths(
357     const std::vector<std::string>& virtual_disk_paths) {
358   Json::Value virtual_disks_json_obj(Json::arrayValue);
359   for (const auto& arg : virtual_disk_paths) {
360     virtual_disks_json_obj.append(arg);
361   }
362   (*Dictionary())[kVirtualDiskPaths] = virtual_disks_json_obj;
363 }
364 
kernel_log_pipe_name() const365 std::string CuttlefishConfig::InstanceSpecific::kernel_log_pipe_name() const {
366   return cvd::AbsolutePath(PerInstanceInternalPath("kernel-log-pipe"));
367 }
368 
console_pipe_name() const369 std::string CuttlefishConfig::InstanceSpecific::console_pipe_name() const {
370   return cvd::AbsolutePath(PerInstanceInternalPath("console-pipe"));
371 }
372 
deprecated_boot_completed() const373 bool CuttlefishConfig::deprecated_boot_completed() const {
374   return (*dictionary_)[kDeprecatedBootCompleted].asBool();
375 }
set_deprecated_boot_completed(bool deprecated_boot_completed)376 void CuttlefishConfig::set_deprecated_boot_completed(
377     bool deprecated_boot_completed) {
378   (*dictionary_)[kDeprecatedBootCompleted] = deprecated_boot_completed;
379 }
380 
access_kregistry_path() const381 std::string CuttlefishConfig::InstanceSpecific::access_kregistry_path() const {
382   return cvd::AbsolutePath(PerInstancePath("access-kregistry"));
383 }
384 
console_path() const385 std::string CuttlefishConfig::InstanceSpecific::console_path() const {
386   return cvd::AbsolutePath(PerInstancePath("console"));
387 }
388 
logcat_path() const389 std::string CuttlefishConfig::InstanceSpecific::logcat_path() const {
390   return cvd::AbsolutePath(PerInstancePath("logcat"));
391 }
392 
launcher_monitor_socket_path() const393 std::string CuttlefishConfig::InstanceSpecific::launcher_monitor_socket_path()
394     const {
395   return cvd::AbsolutePath(PerInstancePath("launcher_monitor.sock"));
396 }
397 
launcher_log_path() const398 std::string CuttlefishConfig::InstanceSpecific::launcher_log_path() const {
399   return cvd::AbsolutePath(PerInstancePath("launcher.log"));
400 }
401 
sdcard_path() const402 std::string CuttlefishConfig::InstanceSpecific::sdcard_path() const {
403   return cvd::AbsolutePath(PerInstancePath("sdcard.img"));
404 }
405 
mobile_bridge_name() const406 std::string CuttlefishConfig::InstanceSpecific::mobile_bridge_name() const {
407   return (*Dictionary())[kMobileBridgeName].asString();
408 }
set_mobile_bridge_name(const std::string & mobile_bridge_name)409 void CuttlefishConfig::MutableInstanceSpecific::set_mobile_bridge_name(
410     const std::string& mobile_bridge_name) {
411   (*Dictionary())[kMobileBridgeName] = mobile_bridge_name;
412 }
413 
mobile_tap_name() const414 std::string CuttlefishConfig::InstanceSpecific::mobile_tap_name() const {
415   return (*Dictionary())[kMobileTapName].asString();
416 }
set_mobile_tap_name(const std::string & mobile_tap_name)417 void CuttlefishConfig::MutableInstanceSpecific::set_mobile_tap_name(
418     const std::string& mobile_tap_name) {
419   (*Dictionary())[kMobileTapName] = mobile_tap_name;
420 }
421 
wifi_tap_name() const422 std::string CuttlefishConfig::InstanceSpecific::wifi_tap_name() const {
423   return (*Dictionary())[kWifiTapName].asString();
424 }
set_wifi_tap_name(const std::string & wifi_tap_name)425 void CuttlefishConfig::MutableInstanceSpecific::set_wifi_tap_name(
426     const std::string& wifi_tap_name) {
427   (*Dictionary())[kWifiTapName] = wifi_tap_name;
428 }
429 
vsock_guest_cid() const430 int CuttlefishConfig::InstanceSpecific::vsock_guest_cid() const {
431   return (*Dictionary())[kVsockGuestCid].asInt();
432 }
433 
set_vsock_guest_cid(int vsock_guest_cid)434 void CuttlefishConfig::MutableInstanceSpecific::set_vsock_guest_cid(
435     int vsock_guest_cid) {
436   (*Dictionary())[kVsockGuestCid] = vsock_guest_cid;
437 }
438 
uuid() const439 std::string CuttlefishConfig::InstanceSpecific::uuid() const {
440   return (*Dictionary())[kUuid].asString();
441 }
set_uuid(const std::string & uuid)442 void CuttlefishConfig::MutableInstanceSpecific::set_uuid(const std::string& uuid) {
443   (*Dictionary())[kUuid] = uuid;
444 }
445 
set_cuttlefish_env_path(const std::string & path)446 void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) {
447   SetPath(kCuttlefishEnvPath, path);
448 }
cuttlefish_env_path() const449 std::string CuttlefishConfig::cuttlefish_env_path() const {
450   return (*dictionary_)[kCuttlefishEnvPath].asString();
451 }
452 
stringToAdbMode(std::string mode)453 static AdbMode stringToAdbMode(std::string mode) {
454   std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
455   if (mode == "vsock_tunnel") {
456     return AdbMode::VsockTunnel;
457   } else if (mode == "vsock_half_tunnel") {
458     return AdbMode::VsockHalfTunnel;
459   } else if (mode == "native_vsock") {
460     return AdbMode::NativeVsock;
461   } else {
462     return AdbMode::Unknown;
463   }
464 }
465 
adb_mode() const466 std::set<AdbMode> CuttlefishConfig::adb_mode() const {
467   std::set<AdbMode> args_set;
468   for (auto& mode : (*dictionary_)[kAdbMode]) {
469     args_set.insert(stringToAdbMode(mode.asString()));
470   }
471   return args_set;
472 }
473 
set_adb_mode(const std::set<std::string> & mode)474 void CuttlefishConfig::set_adb_mode(const std::set<std::string>& mode) {
475   Json::Value mode_json_obj(Json::arrayValue);
476   for (const auto& arg : mode) {
477     mode_json_obj.append(arg);
478   }
479   (*dictionary_)[kAdbMode] = mode_json_obj;
480 }
481 
host_port() const482 int CuttlefishConfig::InstanceSpecific::host_port() const {
483   return (*Dictionary())[kHostPort].asInt();
484 }
485 
set_host_port(int host_port)486 void CuttlefishConfig::MutableInstanceSpecific::set_host_port(int host_port) {
487   (*Dictionary())[kHostPort] = host_port;
488 }
489 
adb_ip_and_port() const490 std::string CuttlefishConfig::InstanceSpecific::adb_ip_and_port() const {
491   return (*Dictionary())[kAdbIPAndPort].asString();
492 }
493 
set_adb_ip_and_port(const std::string & ip_port)494 void CuttlefishConfig::MutableInstanceSpecific::set_adb_ip_and_port(
495     const std::string& ip_port) {
496   (*Dictionary())[kAdbIPAndPort] = ip_port;
497 }
498 
adb_device_name() const499 std::string CuttlefishConfig::InstanceSpecific::adb_device_name() const {
500   if (adb_ip_and_port() != "") {
501     return adb_ip_and_port();
502   }
503   LOG(ERROR) << "no adb_mode found, returning bad device name";
504   return "NO_ADB_MODE_SET_NO_VALID_DEVICE_NAME";
505 }
506 
device_title() const507 std::string CuttlefishConfig::InstanceSpecific::device_title() const {
508   return (*Dictionary())[kDeviceTitle].asString();
509 }
510 
set_device_title(const std::string & title)511 void CuttlefishConfig::MutableInstanceSpecific::set_device_title(
512     const std::string& title) {
513   (*Dictionary())[kDeviceTitle] = title;
514 }
515 
setupwizard_mode() const516 std::string CuttlefishConfig::setupwizard_mode() const {
517   return (*dictionary_)[kSetupWizardMode].asString();
518 }
519 
set_setupwizard_mode(const std::string & mode)520 void CuttlefishConfig::set_setupwizard_mode(const std::string& mode) {
521   (*dictionary_)[kSetupWizardMode] = mode;
522 }
523 
qemu_binary() const524 std::string CuttlefishConfig::qemu_binary() const {
525   return (*dictionary_)[kQemuBinary].asString();
526 }
527 
set_qemu_binary(const std::string & qemu_binary)528 void CuttlefishConfig::set_qemu_binary(const std::string& qemu_binary) {
529   (*dictionary_)[kQemuBinary] = qemu_binary;
530 }
531 
crosvm_binary() const532 std::string CuttlefishConfig::crosvm_binary() const {
533   return (*dictionary_)[kCrosvmBinary].asString();
534 }
535 
set_crosvm_binary(const std::string & crosvm_binary)536 void CuttlefishConfig::set_crosvm_binary(const std::string& crosvm_binary) {
537   (*dictionary_)[kCrosvmBinary] = crosvm_binary;
538 }
539 
console_forwarder_binary() const540 std::string CuttlefishConfig::console_forwarder_binary() const {
541   return (*dictionary_)[kConsoleForwarderBinary].asString();
542 }
543 
set_console_forwarder_binary(const std::string & binary)544 void CuttlefishConfig::set_console_forwarder_binary(
545     const std::string& binary) {
546   (*dictionary_)[kConsoleForwarderBinary] = binary;
547 }
548 
kernel_log_monitor_binary() const549 std::string CuttlefishConfig::kernel_log_monitor_binary() const {
550   return (*dictionary_)[kKernelLogMonitorBinary].asString();
551 }
552 
set_kernel_log_monitor_binary(const std::string & kernel_log_monitor_binary)553 void CuttlefishConfig::set_kernel_log_monitor_binary(
554     const std::string& kernel_log_monitor_binary) {
555   (*dictionary_)[kKernelLogMonitorBinary] = kernel_log_monitor_binary;
556 }
557 
enable_vnc_server() const558 bool CuttlefishConfig::enable_vnc_server() const {
559   return (*dictionary_)[kEnableVncServer].asBool();
560 }
561 
set_enable_vnc_server(bool enable_vnc_server)562 void CuttlefishConfig::set_enable_vnc_server(bool enable_vnc_server) {
563   (*dictionary_)[kEnableVncServer] = enable_vnc_server;
564 }
565 
vnc_server_binary() const566 std::string CuttlefishConfig::vnc_server_binary() const {
567   return (*dictionary_)[kVncServerBinary].asString();
568 }
569 
set_vnc_server_binary(const std::string & vnc_server_binary)570 void CuttlefishConfig::set_vnc_server_binary(
571     const std::string& vnc_server_binary) {
572   (*dictionary_)[kVncServerBinary] = vnc_server_binary;
573 }
574 
vnc_server_port() const575 int CuttlefishConfig::InstanceSpecific::vnc_server_port() const {
576   return (*Dictionary())[kVncServerPort].asInt();
577 }
578 
set_vnc_server_port(int vnc_server_port)579 void CuttlefishConfig::MutableInstanceSpecific::set_vnc_server_port(int vnc_server_port) {
580   (*Dictionary())[kVncServerPort] = vnc_server_port;
581 }
582 
vehicle_hal_server_port() const583 int CuttlefishConfig::InstanceSpecific::vehicle_hal_server_port() const {
584   return (*Dictionary())[kVehicleHalServerPort].asInt();
585 }
586 
set_vehicle_hal_server_port(int vehicle_hal_server_port)587 void CuttlefishConfig::MutableInstanceSpecific::set_vehicle_hal_server_port(int vehicle_hal_server_port) {
588   (*Dictionary())[kVehicleHalServerPort] = vehicle_hal_server_port;
589 }
590 
set_enable_webrtc(bool enable_webrtc)591 void CuttlefishConfig::set_enable_webrtc(bool enable_webrtc) {
592   (*dictionary_)[kEnableWebRTC] = enable_webrtc;
593 }
594 
enable_webrtc() const595 bool CuttlefishConfig::enable_webrtc() const {
596   return (*dictionary_)[kEnableWebRTC].asBool();
597 }
598 
set_webrtc_binary(const std::string & webrtc_binary)599 void CuttlefishConfig::set_webrtc_binary(const std::string& webrtc_binary) {
600   (*dictionary_)[kWebRTCBinary] = webrtc_binary;
601 }
602 
webrtc_binary() const603 std::string CuttlefishConfig::webrtc_binary() const {
604   return (*dictionary_)[kWebRTCBinary].asString();
605 }
606 
set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server)607 void CuttlefishConfig::set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server) {
608   (*dictionary_)[kEnableVehicleHalServer] = enable_vehicle_hal_grpc_server;
609 }
610 
enable_vehicle_hal_grpc_server() const611 bool CuttlefishConfig::enable_vehicle_hal_grpc_server() const {
612   return (*dictionary_)[kEnableVehicleHalServer].asBool();
613 }
614 
set_vehicle_hal_grpc_server_binary(const std::string & vehicle_hal_server_binary)615 void CuttlefishConfig::set_vehicle_hal_grpc_server_binary(const std::string& vehicle_hal_server_binary) {
616   (*dictionary_)[kVehicleHalServerBinary] = vehicle_hal_server_binary;
617 }
618 
vehicle_hal_grpc_server_binary() const619 std::string CuttlefishConfig::vehicle_hal_grpc_server_binary() const {
620   return (*dictionary_)[kVehicleHalServerBinary].asString();
621 }
622 
set_webrtc_assets_dir(const std::string & webrtc_assets_dir)623 void CuttlefishConfig::set_webrtc_assets_dir(const std::string& webrtc_assets_dir) {
624   (*dictionary_)[kWebRTCAssetsDir] = webrtc_assets_dir;
625 }
626 
webrtc_assets_dir() const627 std::string CuttlefishConfig::webrtc_assets_dir() const {
628   return (*dictionary_)[kWebRTCAssetsDir].asString();
629 }
630 
set_webrtc_public_ip(const std::string & webrtc_public_ip)631 void CuttlefishConfig::set_webrtc_public_ip(
632         const std::string& webrtc_public_ip) {
633   (*dictionary_)[kWebRTCPublicIP] = webrtc_public_ip;
634 }
635 
webrtc_public_ip() const636 std::string CuttlefishConfig::webrtc_public_ip() const {
637   return (*dictionary_)[kWebRTCPublicIP].asString();
638 }
639 
set_webrtc_enable_adb_websocket(bool enable)640 void CuttlefishConfig::set_webrtc_enable_adb_websocket(bool enable) {
641     (*dictionary_)[kWebRTCEnableADBWebSocket] = enable;
642 }
643 
webrtc_enable_adb_websocket() const644 bool CuttlefishConfig::webrtc_enable_adb_websocket() const {
645     return (*dictionary_)[kWebRTCEnableADBWebSocket].asBool();
646 }
647 
restart_subprocesses() const648 bool CuttlefishConfig::restart_subprocesses() const {
649   return (*dictionary_)[kRestartSubprocesses].asBool();
650 }
651 
set_restart_subprocesses(bool restart_subprocesses)652 void CuttlefishConfig::set_restart_subprocesses(bool restart_subprocesses) {
653   (*dictionary_)[kRestartSubprocesses] = restart_subprocesses;
654 }
655 
run_adb_connector() const656 bool CuttlefishConfig::run_adb_connector() const {
657   return (*dictionary_)[kRunAdbConnector].asBool();
658 }
659 
set_run_adb_connector(bool run_adb_connector)660 void CuttlefishConfig::set_run_adb_connector(bool run_adb_connector) {
661   (*dictionary_)[kRunAdbConnector] = run_adb_connector;
662 }
663 
adb_connector_binary() const664 std::string CuttlefishConfig::adb_connector_binary() const {
665   return (*dictionary_)[kAdbConnectorBinary].asString();
666 }
667 
set_adb_connector_binary(const std::string & adb_connector_binary)668 void CuttlefishConfig::set_adb_connector_binary(
669     const std::string& adb_connector_binary) {
670   (*dictionary_)[kAdbConnectorBinary] = adb_connector_binary;
671 }
672 
socket_vsock_proxy_binary() const673 std::string CuttlefishConfig::socket_vsock_proxy_binary() const {
674   return (*dictionary_)[kSocketVsockProxyBinary].asString();
675 }
676 
set_socket_vsock_proxy_binary(const std::string & socket_vsock_proxy_binary)677 void CuttlefishConfig::set_socket_vsock_proxy_binary(
678     const std::string& socket_vsock_proxy_binary) {
679   (*dictionary_)[kSocketVsockProxyBinary] = socket_vsock_proxy_binary;
680 }
681 
run_as_daemon() const682 bool CuttlefishConfig::run_as_daemon() const {
683   return (*dictionary_)[kRunAsDaemon].asBool();
684 }
685 
set_run_as_daemon(bool run_as_daemon)686 void CuttlefishConfig::set_run_as_daemon(bool run_as_daemon) {
687   (*dictionary_)[kRunAsDaemon] = run_as_daemon;
688 }
data_policy() const689 std::string CuttlefishConfig::data_policy() const {
690   return (*dictionary_)[kDataPolicy].asString();
691 }
692 
set_data_policy(const std::string & data_policy)693 void CuttlefishConfig::set_data_policy(const std::string& data_policy) {
694   (*dictionary_)[kDataPolicy] = data_policy;
695 }
696 
blank_data_image_mb() const697 int CuttlefishConfig::blank_data_image_mb() const {
698   return (*dictionary_)[kBlankDataImageMb].asInt();
699 }
700 
set_blank_data_image_mb(int blank_data_image_mb)701 void CuttlefishConfig::set_blank_data_image_mb(int blank_data_image_mb) {
702   (*dictionary_)[kBlankDataImageMb] = blank_data_image_mb;
703 }
704 
blank_data_image_fmt() const705 std::string CuttlefishConfig::blank_data_image_fmt() const {
706   return (*dictionary_)[kBlankDataImageFmt].asString();
707 }
708 
set_blank_data_image_fmt(const std::string & blank_data_image_fmt)709 void CuttlefishConfig::set_blank_data_image_fmt(const std::string& blank_data_image_fmt) {
710   (*dictionary_)[kBlankDataImageFmt] = blank_data_image_fmt;
711 }
712 
713 
set_logcat_mode(const std::string & mode)714 void CuttlefishConfig::set_logcat_mode(const std::string& mode) {
715   (*dictionary_)[kLogcatMode] = mode;
716 }
717 
logcat_mode() const718 std::string CuttlefishConfig::logcat_mode() const {
719   return (*dictionary_)[kLogcatMode].asString();
720 }
721 
set_logcat_receiver_binary(const std::string & binary)722 void CuttlefishConfig::set_logcat_receiver_binary(const std::string& binary) {
723   SetPath(kLogcatReceiverBinary, binary);
724 }
725 
logcat_receiver_binary() const726 std::string CuttlefishConfig::logcat_receiver_binary() const {
727   return (*dictionary_)[kLogcatReceiverBinary].asString();
728 }
729 
set_config_server_binary(const std::string & binary)730 void CuttlefishConfig::set_config_server_binary(const std::string& binary) {
731   SetPath(kConfigServerBinary, binary);
732 }
733 
config_server_binary() const734 std::string CuttlefishConfig::config_server_binary() const {
735   return (*dictionary_)[kConfigServerBinary].asString();
736 }
737 
enable_tombstone_receiver() const738 bool CuttlefishConfig::enable_tombstone_receiver() const {
739   return (*dictionary_)[kRunTombstoneReceiver].asBool();
740 }
741 
set_enable_tombstone_receiver(bool enable_tombstone_receiver)742 void CuttlefishConfig::set_enable_tombstone_receiver(bool enable_tombstone_receiver) {
743   (*dictionary_)[kRunTombstoneReceiver] = enable_tombstone_receiver;
744 }
745 
tombstone_receiver_binary() const746 std::string CuttlefishConfig::tombstone_receiver_binary() const {
747   return (*dictionary_)[kTombstoneReceiverBinary].asString();
748 }
749 
set_tombstone_receiver_binary(const std::string & e2e_test_binary)750 void CuttlefishConfig::set_tombstone_receiver_binary(const std::string& e2e_test_binary) {
751   (*dictionary_)[kTombstoneReceiverBinary] = e2e_test_binary;
752 }
753 
use_bootloader() const754 bool CuttlefishConfig::use_bootloader() const {
755   return (*dictionary_)[kUseBootloader].asBool();
756 }
757 
set_use_bootloader(bool use_bootloader)758 void CuttlefishConfig::set_use_bootloader(bool use_bootloader) {
759   (*dictionary_)[kUseBootloader] = use_bootloader;
760 }
761 
bootloader() const762 std::string CuttlefishConfig::bootloader() const {
763   return (*dictionary_)[kBootloader].asString();
764 }
765 
set_bootloader(const std::string & bootloader)766 void CuttlefishConfig::set_bootloader(const std::string& bootloader) {
767   SetPath(kBootloader, bootloader);
768 }
769 
set_boot_slot(const std::string & boot_slot)770 void CuttlefishConfig::set_boot_slot(const std::string& boot_slot) {
771   (*dictionary_)[kBootSlot] = boot_slot;
772 }
773 
boot_slot() const774 std::string CuttlefishConfig::boot_slot() const {
775   return (*dictionary_)[kBootSlot].asString();
776 }
777 
set_webrtc_certs_dir(const std::string & certs_dir)778 void CuttlefishConfig::set_webrtc_certs_dir(const std::string& certs_dir) {
779   (*dictionary_)[kWebRTCCertsDir] = certs_dir;
780 }
781 
webrtc_certs_dir() const782 std::string CuttlefishConfig::webrtc_certs_dir() const {
783   return (*dictionary_)[kWebRTCCertsDir].asString();
784 }
785 
touch_socket_path() const786 std::string CuttlefishConfig::InstanceSpecific::touch_socket_path() const {
787   return PerInstanceInternalPath("touch.sock");
788 }
789 
keyboard_socket_path() const790 std::string CuttlefishConfig::InstanceSpecific::keyboard_socket_path() const {
791   return PerInstanceInternalPath("keyboard.sock");
792 }
793 
frames_socket_path() const794 std::string CuttlefishConfig::InstanceSpecific::frames_socket_path() const {
795   return PerInstanceInternalPath("frames.sock");
796 }
797 
set_loop_max_part(int loop_max_part)798 void CuttlefishConfig::set_loop_max_part(int loop_max_part) {
799   (*dictionary_)[kLoopMaxPart] = loop_max_part;
800 }
loop_max_part() const801 int CuttlefishConfig::loop_max_part() const {
802   return (*dictionary_)[kLoopMaxPart].asInt();
803 }
804 
set_guest_enforce_security(bool guest_enforce_security)805 void CuttlefishConfig::set_guest_enforce_security(bool guest_enforce_security) {
806   (*dictionary_)[kGuestEnforceSecurity] = guest_enforce_security;
807 }
guest_enforce_security() const808 bool CuttlefishConfig::guest_enforce_security() const {
809   return (*dictionary_)[kGuestEnforceSecurity].asBool();
810 }
811 
set_guest_audit_security(bool guest_audit_security)812 void CuttlefishConfig::set_guest_audit_security(bool guest_audit_security) {
813   (*dictionary_)[kGuestAuditSecurity] = guest_audit_security;
814 }
guest_audit_security() const815 bool CuttlefishConfig::guest_audit_security() const {
816   return (*dictionary_)[kGuestAuditSecurity].asBool();
817 }
818 
set_guest_force_normal_boot(bool guest_force_normal_boot)819 void CuttlefishConfig::set_guest_force_normal_boot(bool guest_force_normal_boot) {
820   (*dictionary_)[kGuestForceNormalBoot] = guest_force_normal_boot;
821 }
guest_force_normal_boot() const822 bool CuttlefishConfig::guest_force_normal_boot() const {
823   return (*dictionary_)[kGuestForceNormalBoot].asBool();
824 }
825 
set_wifi_mac_address(const std::array<unsigned char,6> & mac_address)826 void CuttlefishConfig::MutableInstanceSpecific::set_wifi_mac_address(
827     const std::array<unsigned char, 6>& mac_address) {
828   Json::Value mac_address_obj(Json::arrayValue);
829   for (const auto& num : mac_address) {
830     mac_address_obj.append(num);
831   }
832   (*Dictionary())[kWifiMacAddress] = mac_address_obj;
833 }
834 
wifi_mac_address() const835 std::array<unsigned char, 6> CuttlefishConfig::InstanceSpecific::wifi_mac_address() const {
836   std::array<unsigned char, 6> mac_address{0, 0, 0, 0, 0, 0};
837   auto mac_address_obj = (*Dictionary())[kWifiMacAddress];
838   if (mac_address_obj.size() != 6) {
839     LOG(ERROR) << kWifiMacAddress << " entry had wrong size";
840     return {};
841   }
842   for (int i = 0; i < 6; i++) {
843     mac_address[i] = mac_address_obj[i].asInt();
844   }
845   return mac_address;
846 }
847 
set_boot_image_kernel_cmdline(std::string boot_image_kernel_cmdline)848 void CuttlefishConfig::set_boot_image_kernel_cmdline(std::string boot_image_kernel_cmdline) {
849   Json::Value args_json_obj(Json::arrayValue);
850   for (const auto& arg : android::base::Split(boot_image_kernel_cmdline, " ")) {
851     args_json_obj.append(arg);
852   }
853   (*dictionary_)[kBootImageKernelCmdline] = args_json_obj;
854 }
boot_image_kernel_cmdline() const855 std::vector<std::string> CuttlefishConfig::boot_image_kernel_cmdline() const {
856   std::vector<std::string> cmdline;
857   for (const Json::Value& arg : (*dictionary_)[kBootImageKernelCmdline]) {
858     cmdline.push_back(arg.asString());
859   }
860   return cmdline;
861 }
862 
set_extra_kernel_cmdline(std::string extra_cmdline)863 void CuttlefishConfig::set_extra_kernel_cmdline(std::string extra_cmdline) {
864   Json::Value args_json_obj(Json::arrayValue);
865   for (const auto& arg : android::base::Split(extra_cmdline, " ")) {
866     args_json_obj.append(arg);
867   }
868   (*dictionary_)[kExtraKernelCmdline] = args_json_obj;
869 }
extra_kernel_cmdline() const870 std::vector<std::string> CuttlefishConfig::extra_kernel_cmdline() const {
871   std::vector<std::string> cmdline;
872   for (const Json::Value& arg : (*dictionary_)[kExtraKernelCmdline]) {
873     cmdline.push_back(arg.asString());
874   }
875   return cmdline;
876 }
877 
878 // Creates the (initially empty) config object and populates it with values from
879 // the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
880 // Returns nullptr if there was an error loading from file
BuildConfigImpl()881 /*static*/ CuttlefishConfig* CuttlefishConfig::BuildConfigImpl() {
882   auto config_file_path = cvd::StringFromEnv(kCuttlefishConfigEnvVarName,
883                                              vsoc::GetGlobalConfigFileLink());
884   auto ret = new CuttlefishConfig();
885   if (ret) {
886     auto loaded = ret->LoadFromFile(config_file_path.c_str());
887     if (!loaded) {
888       delete ret;
889       return nullptr;
890     }
891   }
892   return ret;
893 }
894 
Get()895 /*static*/ const CuttlefishConfig* CuttlefishConfig::Get() {
896   static std::shared_ptr<CuttlefishConfig> config(BuildConfigImpl());
897   return config.get();
898 }
899 
CuttlefishConfig()900 CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {}
901 // Can't use '= default' on the header because the compiler complains of
902 // Json::Value being an incomplete type
903 CuttlefishConfig::~CuttlefishConfig() = default;
904 
905 CuttlefishConfig::CuttlefishConfig(CuttlefishConfig&&) = default;
906 CuttlefishConfig& CuttlefishConfig::operator=(CuttlefishConfig&&) = default;
907 
LoadFromFile(const char * file)908 bool CuttlefishConfig::LoadFromFile(const char* file) {
909   auto real_file_path = cvd::AbsolutePath(file);
910   if (real_file_path.empty()) {
911     LOG(ERROR) << "Could not get real path for file " << file;
912     return false;
913   }
914   Json::Reader reader;
915   std::ifstream ifs(real_file_path);
916   if (!reader.parse(ifs, *dictionary_)) {
917     LOG(ERROR) << "Could not read config file " << file << ": "
918                << reader.getFormattedErrorMessages();
919     return false;
920   }
921   return true;
922 }
SaveToFile(const std::string & file) const923 bool CuttlefishConfig::SaveToFile(const std::string& file) const {
924   std::ofstream ofs(file);
925   if (!ofs.is_open()) {
926     LOG(ERROR) << "Unable to write to file " << file;
927     return false;
928   }
929   ofs << *dictionary_;
930   return !ofs.fail();
931 }
932 
AssemblyPath(const std::string & file_name) const933 std::string CuttlefishConfig::AssemblyPath(
934     const std::string& file_name) const {
935   return cvd::AbsolutePath(assembly_dir() + "/" + file_name);
936 }
937 
composite_disk_path() const938 std::string CuttlefishConfig::composite_disk_path() const {
939   return AssemblyPath("composite.img");
940 }
941 
PerInstancePath(const char * file_name) const942 std::string CuttlefishConfig::InstanceSpecific::PerInstancePath(
943     const char* file_name) const {
944   return (instance_dir() + "/") + file_name;
945 }
946 
PerInstanceInternalPath(const char * file_name) const947 std::string CuttlefishConfig::InstanceSpecific::PerInstanceInternalPath(
948     const char* file_name) const {
949   if (file_name[0] == '\0') {
950     // Don't append a / if file_name is empty.
951     return PerInstancePath(kInternalDirName);
952   }
953   auto relative_path = (std::string(kInternalDirName) + "/") + file_name;
954   return PerInstancePath(relative_path.c_str());
955 }
956 
instance_name() const957 std::string CuttlefishConfig::InstanceSpecific::instance_name() const {
958   return ForCurrentInstance("cvd-");
959 }
960 
ForInstance(int num)961 CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForInstance(int num) {
962   return MutableInstanceSpecific(this, std::to_string(num));
963 }
964 
ForInstance(int num) const965 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForInstance(int num) const {
966   return InstanceSpecific(this, std::to_string(num));
967 }
968 
ForDefaultInstance() const969 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForDefaultInstance() const {
970   return InstanceSpecific(this, std::to_string(GetInstance()));
971 }
972 
Instances() const973 std::vector<CuttlefishConfig::InstanceSpecific> CuttlefishConfig::Instances() const {
974   const auto& json = (*dictionary_)[kInstances];
975   std::vector<CuttlefishConfig::InstanceSpecific> instances;
976   for (const auto& name : json.getMemberNames()) {
977     instances.push_back(CuttlefishConfig::InstanceSpecific(this, name));
978   }
979   return instances;
980 }
981 
GetInstance()982 int GetInstance() {
983   static int instance_id = InstanceFromEnvironment();
984   return instance_id;
985 }
986 
GetGlobalConfigFileLink()987 std::string GetGlobalConfigFileLink() {
988   return cvd::StringFromEnv("HOME", ".") + "/.cuttlefish_config.json";
989 }
990 
ForCurrentInstance(const char * prefix)991 std::string ForCurrentInstance(const char* prefix) {
992   std::ostringstream stream;
993   stream << prefix << std::setfill('0') << std::setw(2) << GetInstance();
994   return stream.str();
995 }
ForCurrentInstance(int base)996 int ForCurrentInstance(int base) { return base + GetInstance() - 1; }
997 
RandomSerialNumber(const std::string & prefix)998 std::string RandomSerialNumber(const std::string& prefix) {
999   const char hex_characters[] = "0123456789ABCDEF";
1000   std::srand(time(0));
1001   char str[10];
1002   for(int i=0; i<10; i++){
1003     str[i] = hex_characters[rand() % strlen(hex_characters)];
1004   }
1005   return prefix + str;
1006 }
1007 
GetDefaultPerInstanceDir()1008 std::string GetDefaultPerInstanceDir() {
1009   std::ostringstream stream;
1010   stream << std::getenv("HOME") << "/cuttlefish_runtime";
1011   return stream.str();
1012 }
1013 
GetDefaultPerInstanceVsockCid()1014 int GetDefaultPerInstanceVsockCid() {
1015   constexpr int kFirstGuestCid = 3;
1016   return vsoc::HostSupportsVsock() ? ForCurrentInstance(kFirstGuestCid) : 0;
1017 }
1018 
DefaultHostArtifactsPath(const std::string & file_name)1019 std::string DefaultHostArtifactsPath(const std::string& file_name) {
1020   return (cvd::StringFromEnv("ANDROID_HOST_OUT",
1021                              cvd::StringFromEnv("HOME", ".")) +
1022           "/") +
1023          file_name;
1024 }
1025 
DefaultGuestImagePath(const std::string & file_name)1026 std::string DefaultGuestImagePath(const std::string& file_name) {
1027   return (cvd::StringFromEnv("ANDROID_PRODUCT_OUT",
1028                              cvd::StringFromEnv("HOME", ".")) +
1029           "/") +
1030          file_name;
1031 }
1032 
HostSupportsQemuCli()1033 bool HostSupportsQemuCli() {
1034   static bool supported =
1035       std::system(
1036           "/usr/lib/cuttlefish-common/bin/capability_query.py qemu_cli") == 0;
1037   return supported;
1038 }
1039 
HostSupportsVsock()1040 bool HostSupportsVsock() {
1041   static bool supported =
1042       std::system(
1043           "/usr/lib/cuttlefish-common/bin/capability_query.py vsock") == 0;
1044   return supported;
1045 }
1046 }  // namespace vsoc
1047