• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
22 #include <cstdlib>
23 #include <cstring>
24 #include <fstream>
25 #include <iomanip>
26 #include <iterator>
27 #include <sstream>
28 #include <string>
29 #include <time.h>
30 
31 #include <android-base/strings.h>
32 #include <android-base/logging.h>
33 #include <json/json.h>
34 
35 #include "common/libs/utils/environment.h"
36 #include "common/libs/utils/files.h"
37 #include "host/libs/vm_manager/crosvm_manager.h"
38 #include "host/libs/vm_manager/gem5_manager.h"
39 #include "host/libs/vm_manager/qemu_manager.h"
40 
41 namespace cuttlefish {
42 namespace {
43 
44 static constexpr int kDefaultInstance = 1;
45 
InstanceFromString(std::string instance_str)46 int InstanceFromString(std::string instance_str) {
47   if (android::base::StartsWith(instance_str, kVsocUserPrefix)) {
48     instance_str = instance_str.substr(std::string(kVsocUserPrefix).size());
49   } else if (android::base::StartsWith(instance_str, kCvdNamePrefix)) {
50     instance_str = instance_str.substr(std::string(kCvdNamePrefix).size());
51   }
52 
53   int instance = std::stoi(instance_str);
54   if (instance <= 0) {
55     LOG(INFO) << "Failed to interpret \"" << instance_str << "\" as an id, "
56               << "using instance id " << kDefaultInstance;
57     return kDefaultInstance;
58   }
59   return instance;
60 }
61 
InstanceFromEnvironment()62 int InstanceFromEnvironment() {
63   static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE";
64 
65   // CUTTLEFISH_INSTANCE environment variable
66   std::string instance_str = StringFromEnv(kInstanceEnvironmentVariable, "");
67   if (instance_str.empty()) {
68     // Try to get it from the user instead
69     instance_str = StringFromEnv("USER", "");
70 
71     if (instance_str.empty()) {
72       LOG(DEBUG) << "CUTTLEFISH_INSTANCE and USER unset, using instance id "
73                  << kDefaultInstance;
74       return kDefaultInstance;
75     }
76     if (!android::base::StartsWith(instance_str, kVsocUserPrefix)) {
77       // No user or we don't recognize this user
78       LOG(DEBUG) << "Non-vsoc user, using instance id " << kDefaultInstance;
79       return kDefaultInstance;
80     }
81   }
82   return InstanceFromString(instance_str);
83 }
84 
85 const char* kInstances = "instances";
86 
87 
88 }  // namespace
89 
90 const char* const kGpuModeAuto = "auto";
91 const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
92 const char* const kGpuModeDrmVirgl = "drm_virgl";
93 const char* const kGpuModeGfxStream = "gfxstream";
94 
95 const char* const kHwComposerAuto = "auto";
96 const char* const kHwComposerDrm = "drm";
97 const char* const kHwComposerRanchu = "ranchu";
98 
DefaultEnvironmentPath(const char * environment_key,const char * default_value,const char * subpath)99 std::string DefaultEnvironmentPath(const char* environment_key,
100                                    const char* default_value,
101                                    const char* subpath) {
102   return StringFromEnv(environment_key, default_value) + "/" + subpath;
103 }
104 
105 ConfigFragment::~ConfigFragment() = default;
106 
107 static constexpr char kFragments[] = "fragments";
LoadFragment(ConfigFragment & fragment) const108 bool CuttlefishConfig::LoadFragment(ConfigFragment& fragment) const {
109   if (!dictionary_->isMember(kFragments)) {
110     LOG(ERROR) << "Fragments member was missing";
111     return false;
112   }
113   const Json::Value& json_fragments = (*dictionary_)[kFragments];
114   if (!json_fragments.isMember(fragment.Name())) {
115     LOG(ERROR) << "Could not find a fragment called " << fragment.Name();
116     return false;
117   }
118   return fragment.Deserialize(json_fragments[fragment.Name()]);
119 }
SaveFragment(const ConfigFragment & fragment)120 bool CuttlefishConfig::SaveFragment(const ConfigFragment& fragment) {
121   Json::Value& json_fragments = (*dictionary_)[kFragments];
122   if (json_fragments.isMember(fragment.Name())) {
123     LOG(ERROR) << "Already have a fragment called " << fragment.Name();
124     return false;
125   }
126   json_fragments[fragment.Name()] = fragment.Serialize();
127   return true;
128 }
129 
130 static constexpr char kRootDir[] = "root_dir";
root_dir() const131 std::string CuttlefishConfig::root_dir() const {
132   return (*dictionary_)[kRootDir].asString();
133 }
set_root_dir(const std::string & root_dir)134 void CuttlefishConfig::set_root_dir(const std::string& root_dir) {
135   (*dictionary_)[kRootDir] = root_dir;
136 }
137 
138 static constexpr char kVmManager[] = "vm_manager";
vm_manager() const139 std::string CuttlefishConfig::vm_manager() const {
140   return (*dictionary_)[kVmManager].asString();
141 }
set_vm_manager(const std::string & name)142 void CuttlefishConfig::set_vm_manager(const std::string& name) {
143   (*dictionary_)[kVmManager] = name;
144 }
145 
146 static constexpr char kGpuMode[] = "gpu_mode";
gpu_mode() const147 std::string CuttlefishConfig::gpu_mode() const {
148   return (*dictionary_)[kGpuMode].asString();
149 }
set_gpu_mode(const std::string & name)150 void CuttlefishConfig::set_gpu_mode(const std::string& name) {
151   (*dictionary_)[kGpuMode] = name;
152 }
153 
154 static constexpr char kGpuCaptureBinary[] = "gpu_capture_binary";
gpu_capture_binary() const155 std::string CuttlefishConfig::gpu_capture_binary() const {
156   return (*dictionary_)[kGpuCaptureBinary].asString();
157 }
set_gpu_capture_binary(const std::string & name)158 void CuttlefishConfig::set_gpu_capture_binary(const std::string& name) {
159   (*dictionary_)[kGpuCaptureBinary] = name;
160 }
161 
162 static constexpr char kHWComposer[] = "hwcomposer";
hwcomposer() const163 std::string CuttlefishConfig::hwcomposer() const {
164   return (*dictionary_)[kHWComposer].asString();
165 }
set_hwcomposer(const std::string & name)166 void CuttlefishConfig::set_hwcomposer(const std::string& name) {
167   (*dictionary_)[kHWComposer] = name;
168 }
169 
170 static constexpr char kEnableGpuUdmabuf[] = "enable_gpu_udmabuf";
set_enable_gpu_udmabuf(const bool enable_gpu_udmabuf)171 void CuttlefishConfig::set_enable_gpu_udmabuf(const bool enable_gpu_udmabuf) {
172   (*dictionary_)[kEnableGpuUdmabuf] = enable_gpu_udmabuf;
173 }
enable_gpu_udmabuf() const174 bool CuttlefishConfig::enable_gpu_udmabuf() const {
175   return (*dictionary_)[kEnableGpuUdmabuf].asBool();
176 }
177 
178 static constexpr char kEnableGpuAngle[] = "enable_gpu_angle";
set_enable_gpu_angle(const bool enable_gpu_angle)179 void CuttlefishConfig::set_enable_gpu_angle(const bool enable_gpu_angle) {
180   (*dictionary_)[kEnableGpuAngle] = enable_gpu_angle;
181 }
enable_gpu_angle() const182 bool CuttlefishConfig::enable_gpu_angle() const {
183   return (*dictionary_)[kEnableGpuAngle].asBool();
184 }
185 
186 static constexpr char kCpus[] = "cpus";
cpus() const187 int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); }
set_cpus(int cpus)188 void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; }
189 
190 static constexpr char kMemoryMb[] = "memory_mb";
memory_mb() const191 int CuttlefishConfig::memory_mb() const {
192   return (*dictionary_)[kMemoryMb].asInt();
193 }
set_memory_mb(int memory_mb)194 void CuttlefishConfig::set_memory_mb(int memory_mb) {
195   (*dictionary_)[kMemoryMb] = memory_mb;
196 }
197 
198 static constexpr char kDisplayConfigs[] = "display_configs";
199 static constexpr char kXRes[] = "x_res";
200 static constexpr char kYRes[] = "y_res";
201 static constexpr char kDpi[] = "dpi";
202 static constexpr char kRefreshRateHz[] = "refresh_rate_hz";
203 std::vector<CuttlefishConfig::DisplayConfig>
display_configs() const204 CuttlefishConfig::display_configs() const {
205   std::vector<DisplayConfig> display_configs;
206   for (auto& display_config_json : (*dictionary_)[kDisplayConfigs]) {
207     DisplayConfig display_config = {};
208     display_config.width = display_config_json[kXRes].asInt();
209     display_config.height = display_config_json[kYRes].asInt();
210     display_config.dpi = display_config_json[kDpi].asInt();
211     display_config.refresh_rate_hz =
212         display_config_json[kRefreshRateHz].asInt();
213     display_configs.emplace_back(std::move(display_config));
214   }
215   return display_configs;
216 }
set_display_configs(const std::vector<DisplayConfig> & display_configs)217 void CuttlefishConfig::set_display_configs(
218     const std::vector<DisplayConfig>& display_configs) {
219   Json::Value display_configs_json(Json::arrayValue);
220 
221   for (const DisplayConfig& display_configs : display_configs) {
222     Json::Value display_config_json(Json::objectValue);
223     display_config_json[kXRes] = display_configs.width;
224     display_config_json[kYRes] = display_configs.height;
225     display_config_json[kDpi] = display_configs.dpi;
226     display_config_json[kRefreshRateHz] = display_configs.refresh_rate_hz;
227     display_configs_json.append(display_config_json);
228   }
229 
230   (*dictionary_)[kDisplayConfigs] = display_configs_json;
231 }
232 
SetPath(const std::string & key,const std::string & path)233 void CuttlefishConfig::SetPath(const std::string& key,
234                                const std::string& path) {
235   if (!path.empty()) {
236     (*dictionary_)[key] = AbsolutePath(path);
237   }
238 }
239 
240 static constexpr char kGdbPort[] = "gdb_port";
gdb_port() const241 int CuttlefishConfig::gdb_port() const {
242   return (*dictionary_)[kGdbPort].asInt();
243 }
set_gdb_port(int port)244 void CuttlefishConfig::set_gdb_port(int port) {
245   (*dictionary_)[kGdbPort] = port;
246 }
247 
248 static constexpr char kDeprecatedBootCompleted[] = "deprecated_boot_completed";
deprecated_boot_completed() const249 bool CuttlefishConfig::deprecated_boot_completed() const {
250   return (*dictionary_)[kDeprecatedBootCompleted].asBool();
251 }
set_deprecated_boot_completed(bool deprecated_boot_completed)252 void CuttlefishConfig::set_deprecated_boot_completed(
253     bool deprecated_boot_completed) {
254   (*dictionary_)[kDeprecatedBootCompleted] = deprecated_boot_completed;
255 }
256 
257 static constexpr char kCuttlefishEnvPath[] = "cuttlefish_env_path";
set_cuttlefish_env_path(const std::string & path)258 void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) {
259   SetPath(kCuttlefishEnvPath, path);
260 }
cuttlefish_env_path() const261 std::string CuttlefishConfig::cuttlefish_env_path() const {
262   return (*dictionary_)[kCuttlefishEnvPath].asString();
263 }
264 
StringToSecureHal(std::string mode)265 static SecureHal StringToSecureHal(std::string mode) {
266   std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
267   if (mode == "keymint") {
268     return SecureHal::Keymint;
269   } else if (mode == "gatekeeper") {
270     return SecureHal::Gatekeeper;
271   } else {
272     return SecureHal::Unknown;
273   }
274 }
275 
276 static constexpr char kSecureHals[] = "secure_hals";
secure_hals() const277 std::set<SecureHal> CuttlefishConfig::secure_hals() const {
278   std::set<SecureHal> args_set;
279   for (auto& hal : (*dictionary_)[kSecureHals]) {
280     args_set.insert(StringToSecureHal(hal.asString()));
281   }
282   return args_set;
283 }
set_secure_hals(const std::set<std::string> & hals)284 void CuttlefishConfig::set_secure_hals(const std::set<std::string>& hals) {
285   Json::Value hals_json_obj(Json::arrayValue);
286   for (const auto& hal : hals) {
287     hals_json_obj.append(hal);
288   }
289   (*dictionary_)[kSecureHals] = hals_json_obj;
290 }
291 
292 static constexpr char kSetupWizardMode[] = "setupwizard_mode";
setupwizard_mode() const293 std::string CuttlefishConfig::setupwizard_mode() const {
294   return (*dictionary_)[kSetupWizardMode].asString();
295 }
set_setupwizard_mode(const std::string & mode)296 void CuttlefishConfig::set_setupwizard_mode(const std::string& mode) {
297   (*dictionary_)[kSetupWizardMode] = mode;
298 }
299 
300 static constexpr char kQemuBinaryDir[] = "qemu_binary_dir";
qemu_binary_dir() const301 std::string CuttlefishConfig::qemu_binary_dir() const {
302   return (*dictionary_)[kQemuBinaryDir].asString();
303 }
set_qemu_binary_dir(const std::string & qemu_binary_dir)304 void CuttlefishConfig::set_qemu_binary_dir(const std::string& qemu_binary_dir) {
305   (*dictionary_)[kQemuBinaryDir] = qemu_binary_dir;
306 }
307 
308 static constexpr char kCrosvmBinary[] = "crosvm_binary";
crosvm_binary() const309 std::string CuttlefishConfig::crosvm_binary() const {
310   return (*dictionary_)[kCrosvmBinary].asString();
311 }
set_crosvm_binary(const std::string & crosvm_binary)312 void CuttlefishConfig::set_crosvm_binary(const std::string& crosvm_binary) {
313   (*dictionary_)[kCrosvmBinary] = crosvm_binary;
314 }
315 
316 static constexpr char kGem5BinaryDir[] = "gem5_binary_dir";
gem5_binary_dir() const317 std::string CuttlefishConfig::gem5_binary_dir() const {
318   return (*dictionary_)[kGem5BinaryDir].asString();
319 }
set_gem5_binary_dir(const std::string & gem5_binary_dir)320 void CuttlefishConfig::set_gem5_binary_dir(const std::string& gem5_binary_dir) {
321   (*dictionary_)[kGem5BinaryDir] = gem5_binary_dir;
322 }
323 
324 static constexpr char kEnableGnssGrpcProxy[] = "enable_gnss_grpc_proxy";
set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy)325 void CuttlefishConfig::set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy) {
326   (*dictionary_)[kEnableGnssGrpcProxy] = enable_gnss_grpc_proxy;
327 }
enable_gnss_grpc_proxy() const328 bool CuttlefishConfig::enable_gnss_grpc_proxy() const {
329   return (*dictionary_)[kEnableGnssGrpcProxy].asBool();
330 }
331 
332 static constexpr char kEnableSandbox[] = "enable_sandbox";
set_enable_sandbox(const bool enable_sandbox)333 void CuttlefishConfig::set_enable_sandbox(const bool enable_sandbox) {
334   (*dictionary_)[kEnableSandbox] = enable_sandbox;
335 }
enable_sandbox() const336 bool CuttlefishConfig::enable_sandbox() const {
337   return (*dictionary_)[kEnableSandbox].asBool();
338 }
339 
340 static constexpr char kSeccompPolicyDir[] = "seccomp_policy_dir";
set_seccomp_policy_dir(const std::string & seccomp_policy_dir)341 void CuttlefishConfig::set_seccomp_policy_dir(const std::string& seccomp_policy_dir) {
342   if (seccomp_policy_dir.empty()) {
343     (*dictionary_)[kSeccompPolicyDir] = seccomp_policy_dir;
344     return;
345   }
346   SetPath(kSeccompPolicyDir, seccomp_policy_dir);
347 }
seccomp_policy_dir() const348 std::string CuttlefishConfig::seccomp_policy_dir() const {
349   return (*dictionary_)[kSeccompPolicyDir].asString();
350 }
351 
352 static constexpr char kEnableWebRTC[] = "enable_webrtc";
set_enable_webrtc(bool enable_webrtc)353 void CuttlefishConfig::set_enable_webrtc(bool enable_webrtc) {
354   (*dictionary_)[kEnableWebRTC] = enable_webrtc;
355 }
enable_webrtc() const356 bool CuttlefishConfig::enable_webrtc() const {
357   return (*dictionary_)[kEnableWebRTC].asBool();
358 }
359 
360 static constexpr char kEnableVehicleHalServer[] = "enable_vehicle_hal_server";
set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server)361 void CuttlefishConfig::set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server) {
362   (*dictionary_)[kEnableVehicleHalServer] = enable_vehicle_hal_grpc_server;
363 }
enable_vehicle_hal_grpc_server() const364 bool CuttlefishConfig::enable_vehicle_hal_grpc_server() const {
365   return (*dictionary_)[kEnableVehicleHalServer].asBool();
366 }
367 
368 static constexpr char kWebRTCAssetsDir[] = "webrtc_assets_dir";
set_webrtc_assets_dir(const std::string & webrtc_assets_dir)369 void CuttlefishConfig::set_webrtc_assets_dir(const std::string& webrtc_assets_dir) {
370   (*dictionary_)[kWebRTCAssetsDir] = webrtc_assets_dir;
371 }
webrtc_assets_dir() const372 std::string CuttlefishConfig::webrtc_assets_dir() const {
373   return (*dictionary_)[kWebRTCAssetsDir].asString();
374 }
375 
376 static constexpr char kWebRTCEnableADBWebSocket[] =
377     "webrtc_enable_adb_websocket";
set_webrtc_enable_adb_websocket(bool enable)378 void CuttlefishConfig::set_webrtc_enable_adb_websocket(bool enable) {
379     (*dictionary_)[kWebRTCEnableADBWebSocket] = enable;
380 }
webrtc_enable_adb_websocket() const381 bool CuttlefishConfig::webrtc_enable_adb_websocket() const {
382     return (*dictionary_)[kWebRTCEnableADBWebSocket].asBool();
383 }
384 
385 static constexpr char kRestartSubprocesses[] = "restart_subprocesses";
restart_subprocesses() const386 bool CuttlefishConfig::restart_subprocesses() const {
387   return (*dictionary_)[kRestartSubprocesses].asBool();
388 }
set_restart_subprocesses(bool restart_subprocesses)389 void CuttlefishConfig::set_restart_subprocesses(bool restart_subprocesses) {
390   (*dictionary_)[kRestartSubprocesses] = restart_subprocesses;
391 }
392 
393 static constexpr char kRunAsDaemon[] = "run_as_daemon";
run_as_daemon() const394 bool CuttlefishConfig::run_as_daemon() const {
395   return (*dictionary_)[kRunAsDaemon].asBool();
396 }
set_run_as_daemon(bool run_as_daemon)397 void CuttlefishConfig::set_run_as_daemon(bool run_as_daemon) {
398   (*dictionary_)[kRunAsDaemon] = run_as_daemon;
399 }
400 
401 static constexpr char kDataPolicy[] = "data_policy";
data_policy() const402 std::string CuttlefishConfig::data_policy() const {
403   return (*dictionary_)[kDataPolicy].asString();
404 }
set_data_policy(const std::string & data_policy)405 void CuttlefishConfig::set_data_policy(const std::string& data_policy) {
406   (*dictionary_)[kDataPolicy] = data_policy;
407 }
408 
409 static constexpr char kBlankDataImageMb[] = "blank_data_image_mb";
blank_data_image_mb() const410 int CuttlefishConfig::blank_data_image_mb() const {
411   return (*dictionary_)[kBlankDataImageMb].asInt();
412 }
set_blank_data_image_mb(int blank_data_image_mb)413 void CuttlefishConfig::set_blank_data_image_mb(int blank_data_image_mb) {
414   (*dictionary_)[kBlankDataImageMb] = blank_data_image_mb;
415 }
416 
417 static constexpr char kBootloader[] = "bootloader";
bootloader() const418 std::string CuttlefishConfig::bootloader() const {
419   return (*dictionary_)[kBootloader].asString();
420 }
set_bootloader(const std::string & bootloader)421 void CuttlefishConfig::set_bootloader(const std::string& bootloader) {
422   SetPath(kBootloader, bootloader);
423 }
424 
425 static constexpr char kBootSlot[] = "boot_slot";
set_boot_slot(const std::string & boot_slot)426 void CuttlefishConfig::set_boot_slot(const std::string& boot_slot) {
427   (*dictionary_)[kBootSlot] = boot_slot;
428 }
boot_slot() const429 std::string CuttlefishConfig::boot_slot() const {
430   return (*dictionary_)[kBootSlot].asString();
431 }
432 
433 static constexpr char kWebRTCCertsDir[] = "webrtc_certs_dir";
set_webrtc_certs_dir(const std::string & certs_dir)434 void CuttlefishConfig::set_webrtc_certs_dir(const std::string& certs_dir) {
435   (*dictionary_)[kWebRTCCertsDir] = certs_dir;
436 }
webrtc_certs_dir() const437 std::string CuttlefishConfig::webrtc_certs_dir() const {
438   return (*dictionary_)[kWebRTCCertsDir].asString();
439 }
440 
441 static constexpr char kSigServerPort[] = "webrtc_sig_server_port";
set_sig_server_port(int port)442 void CuttlefishConfig::set_sig_server_port(int port) {
443   (*dictionary_)[kSigServerPort] = port;
444 }
sig_server_port() const445 int CuttlefishConfig::sig_server_port() const {
446   return (*dictionary_)[kSigServerPort].asInt();
447 }
448 
449 static constexpr char kWebrtcUdpPortRange[] = "webrtc_udp_port_range";
set_webrtc_udp_port_range(std::pair<uint16_t,uint16_t> range)450 void CuttlefishConfig::set_webrtc_udp_port_range(
451     std::pair<uint16_t, uint16_t> range) {
452   Json::Value arr(Json::ValueType::arrayValue);
453   arr[0] = range.first;
454   arr[1] = range.second;
455   (*dictionary_)[kWebrtcUdpPortRange] = arr;
456 }
webrtc_udp_port_range() const457 std::pair<uint16_t, uint16_t> CuttlefishConfig::webrtc_udp_port_range() const {
458   std::pair<uint16_t, uint16_t> ret;
459   ret.first = (*dictionary_)[kWebrtcUdpPortRange][0].asInt();
460   ret.second = (*dictionary_)[kWebrtcUdpPortRange][1].asInt();
461   return ret;
462 }
463 
464 static constexpr char kWebrtcTcpPortRange[] = "webrtc_tcp_port_range";
set_webrtc_tcp_port_range(std::pair<uint16_t,uint16_t> range)465 void CuttlefishConfig::set_webrtc_tcp_port_range(
466     std::pair<uint16_t, uint16_t> range) {
467   Json::Value arr(Json::ValueType::arrayValue);
468   arr[0] = range.first;
469   arr[1] = range.second;
470   (*dictionary_)[kWebrtcTcpPortRange] = arr;
471 }
webrtc_tcp_port_range() const472 std::pair<uint16_t, uint16_t> CuttlefishConfig::webrtc_tcp_port_range() const {
473   std::pair<uint16_t, uint16_t> ret;
474   ret.first = (*dictionary_)[kWebrtcTcpPortRange][0].asInt();
475   ret.second = (*dictionary_)[kWebrtcTcpPortRange][1].asInt();
476   return ret;
477 }
478 
479 static constexpr char kSigServerAddress[] = "webrtc_sig_server_addr";
set_sig_server_address(const std::string & addr)480 void CuttlefishConfig::set_sig_server_address(const std::string& addr) {
481   (*dictionary_)[kSigServerAddress] = addr;
482 }
sig_server_address() const483 std::string CuttlefishConfig::sig_server_address() const {
484   return (*dictionary_)[kSigServerAddress].asString();
485 }
486 
487 static constexpr char kSigServerPath[] = "webrtc_sig_server_path";
set_sig_server_path(const std::string & path)488 void CuttlefishConfig::set_sig_server_path(const std::string& path) {
489   // Don't use SetPath here, it's a URL path not a file system path
490   (*dictionary_)[kSigServerPath] = path;
491 }
sig_server_path() const492 std::string CuttlefishConfig::sig_server_path() const {
493   return (*dictionary_)[kSigServerPath].asString();
494 }
495 
496 static constexpr char kSigServerSecure[] = "webrtc_sig_server_secure";
set_sig_server_secure(bool secure)497 void CuttlefishConfig::set_sig_server_secure(bool secure) {
498   (*dictionary_)[kSigServerSecure] = secure;
499 }
sig_server_secure() const500 bool CuttlefishConfig::sig_server_secure() const {
501   return (*dictionary_)[kSigServerSecure].asBool();
502 }
503 
504 static constexpr char kSigServerStrict[] = "webrtc_sig_server_strict";
set_sig_server_strict(bool strict)505 void CuttlefishConfig::set_sig_server_strict(bool strict) {
506   (*dictionary_)[kSigServerStrict] = strict;
507 }
sig_server_strict() const508 bool CuttlefishConfig::sig_server_strict() const {
509   return (*dictionary_)[kSigServerStrict].asBool();
510 }
511 
512 static constexpr char kSigServerHeadersPath[] =
513     "webrtc_sig_server_headers_path";
set_sig_server_headers_path(const std::string & path)514 void CuttlefishConfig::set_sig_server_headers_path(const std::string& path) {
515   SetPath(kSigServerHeadersPath, path);
516 }
sig_server_headers_path() const517 std::string CuttlefishConfig::sig_server_headers_path() const {
518   return (*dictionary_)[kSigServerHeadersPath].asString();
519 }
520 
521 static constexpr char kRunModemSimulator[] = "enable_modem_simulator";
enable_modem_simulator() const522 bool CuttlefishConfig::enable_modem_simulator() const {
523   return (*dictionary_)[kRunModemSimulator].asBool();
524 }
set_enable_modem_simulator(bool enable_modem_simulator)525 void CuttlefishConfig::set_enable_modem_simulator(bool enable_modem_simulator) {
526   (*dictionary_)[kRunModemSimulator] = enable_modem_simulator;
527 }
528 
529 static constexpr char kModemSimulatorInstanceNumber[] =
530     "modem_simulator_instance_number";
set_modem_simulator_instance_number(int instance_number)531 void CuttlefishConfig::set_modem_simulator_instance_number(
532     int instance_number) {
533   (*dictionary_)[kModemSimulatorInstanceNumber] = instance_number;
534 }
modem_simulator_instance_number() const535 int CuttlefishConfig::modem_simulator_instance_number() const {
536   return (*dictionary_)[kModemSimulatorInstanceNumber].asInt();
537 }
538 
539 static constexpr char kModemSimulatorSimType[] = "modem_simulator_sim_type";
set_modem_simulator_sim_type(int sim_type)540 void CuttlefishConfig::set_modem_simulator_sim_type(int sim_type) {
541   (*dictionary_)[kModemSimulatorSimType] = sim_type;
542 }
modem_simulator_sim_type() const543 int CuttlefishConfig::modem_simulator_sim_type() const {
544   return (*dictionary_)[kModemSimulatorSimType].asInt();
545 }
546 
547 static constexpr char kHostToolsVersion[] = "host_tools_version";
set_host_tools_version(const std::map<std::string,uint32_t> & versions)548 void CuttlefishConfig::set_host_tools_version(
549     const std::map<std::string, uint32_t>& versions) {
550   Json::Value json(Json::objectValue);
551   for (const auto& [key, value] : versions) {
552     json[key] = value;
553   }
554   (*dictionary_)[kHostToolsVersion] = json;
555 }
host_tools_version() const556 std::map<std::string, uint32_t> CuttlefishConfig::host_tools_version() const {
557   if (!dictionary_->isMember(kHostToolsVersion)) {
558     return {};
559   }
560   std::map<std::string, uint32_t> versions;
561   const auto& elem = (*dictionary_)[kHostToolsVersion];
562   for (auto it = elem.begin(); it != elem.end(); it++) {
563     versions[it.key().asString()] = it->asUInt();
564   }
565   return versions;
566 }
567 
568 static constexpr char kGuestEnforceSecurity[] = "guest_enforce_security";
set_guest_enforce_security(bool guest_enforce_security)569 void CuttlefishConfig::set_guest_enforce_security(bool guest_enforce_security) {
570   (*dictionary_)[kGuestEnforceSecurity] = guest_enforce_security;
571 }
guest_enforce_security() const572 bool CuttlefishConfig::guest_enforce_security() const {
573   return (*dictionary_)[kGuestEnforceSecurity].asBool();
574 }
575 
576 static constexpr char kenableHostBluetooth[] = "enable_host_bluetooth";
set_enable_host_bluetooth(bool enable_host_bluetooth)577 void CuttlefishConfig::set_enable_host_bluetooth(bool enable_host_bluetooth) {
578   (*dictionary_)[kenableHostBluetooth] = enable_host_bluetooth;
579 }
enable_host_bluetooth() const580 bool CuttlefishConfig::enable_host_bluetooth() const {
581   return (*dictionary_)[kenableHostBluetooth].asBool();
582 }
583 
584 static constexpr char kEnableMetrics[] = "enable_metrics";
set_enable_metrics(std::string enable_metrics)585 void CuttlefishConfig::set_enable_metrics(std::string enable_metrics) {
586   (*dictionary_)[kEnableMetrics] = kUnknown;
587   if (!enable_metrics.empty()) {
588     switch (enable_metrics.at(0)) {
589       case 'y':
590       case 'Y':
591         (*dictionary_)[kEnableMetrics] = kYes;
592         break;
593       case 'n':
594       case 'N':
595         (*dictionary_)[kEnableMetrics] = kNo;
596         break;
597     }
598   }
599 }
enable_metrics() const600 CuttlefishConfig::Answer CuttlefishConfig::enable_metrics() const {
601   return (CuttlefishConfig::Answer)(*dictionary_)[kEnableMetrics].asInt();
602 }
603 
604 static constexpr char kMetricsBinary[] = "metrics_binary";
set_metrics_binary(const std::string & metrics_binary)605 void CuttlefishConfig::set_metrics_binary(const std::string& metrics_binary) {
606   (*dictionary_)[kMetricsBinary] = metrics_binary;
607 }
metrics_binary() const608 std::string CuttlefishConfig::metrics_binary() const {
609   return (*dictionary_)[kMetricsBinary].asString();
610 }
611 
612 static constexpr char kExtraKernelCmdline[] = "extra_kernel_cmdline";
set_extra_kernel_cmdline(const std::string & extra_cmdline)613 void CuttlefishConfig::set_extra_kernel_cmdline(
614     const std::string& extra_cmdline) {
615   Json::Value args_json_obj(Json::arrayValue);
616   for (const auto& arg : android::base::Split(extra_cmdline, " ")) {
617     args_json_obj.append(arg);
618   }
619   (*dictionary_)[kExtraKernelCmdline] = args_json_obj;
620 }
extra_kernel_cmdline() const621 std::vector<std::string> CuttlefishConfig::extra_kernel_cmdline() const {
622   std::vector<std::string> cmdline;
623   for (const Json::Value& arg : (*dictionary_)[kExtraKernelCmdline]) {
624     cmdline.push_back(arg.asString());
625   }
626   return cmdline;
627 }
628 
629 static constexpr char kExtraBootconfigArgs[] = "extra_bootconfig_args";
set_extra_bootconfig_args(const std::string & extra_bootconfig_args)630 void CuttlefishConfig::set_extra_bootconfig_args(
631     const std::string& extra_bootconfig_args) {
632   Json::Value args_json_obj(Json::arrayValue);
633   for (const auto& arg : android::base::Split(extra_bootconfig_args, " ")) {
634     args_json_obj.append(arg);
635   }
636   (*dictionary_)[kExtraBootconfigArgs] = args_json_obj;
637 }
extra_bootconfig_args() const638 std::vector<std::string> CuttlefishConfig::extra_bootconfig_args() const {
639   std::vector<std::string> bootconfig;
640   for (const Json::Value& arg : (*dictionary_)[kExtraBootconfigArgs]) {
641     bootconfig.push_back(arg.asString());
642   }
643   return bootconfig;
644 }
645 
646 static constexpr char kRilDns[] = "ril_dns";
set_ril_dns(const std::string & ril_dns)647 void CuttlefishConfig::set_ril_dns(const std::string& ril_dns) {
648   (*dictionary_)[kRilDns] = ril_dns;
649 }
ril_dns() const650 std::string CuttlefishConfig::ril_dns() const {
651   return (*dictionary_)[kRilDns].asString();
652 }
653 
654 static constexpr char kKgdb[] = "kgdb";
set_kgdb(bool kgdb)655 void CuttlefishConfig::set_kgdb(bool kgdb) {
656   (*dictionary_)[kKgdb] = kgdb;
657 }
kgdb() const658 bool CuttlefishConfig::kgdb() const {
659   return (*dictionary_)[kKgdb].asBool();
660 }
661 
662 static constexpr char kEnableMinimalMode[] = "enable_minimal_mode";
enable_minimal_mode() const663 bool CuttlefishConfig::enable_minimal_mode() const {
664   return (*dictionary_)[kEnableMinimalMode].asBool();
665 }
set_enable_minimal_mode(bool enable_minimal_mode)666 void CuttlefishConfig::set_enable_minimal_mode(bool enable_minimal_mode) {
667   (*dictionary_)[kEnableMinimalMode] = enable_minimal_mode;
668 }
669 
670 static constexpr char kConsole[] = "console";
set_console(bool console)671 void CuttlefishConfig::set_console(bool console) {
672   (*dictionary_)[kConsole] = console;
673 }
console() const674 bool CuttlefishConfig::console() const {
675   return (*dictionary_)[kConsole].asBool();
676 }
console_dev() const677 std::string CuttlefishConfig::console_dev() const {
678   auto can_use_virtio_console = !kgdb() && !use_bootloader();
679   std::string console_dev;
680   if (can_use_virtio_console ||
681       vm_manager() == vm_manager::Gem5Manager::name()) {
682     // If kgdb and the bootloader are disabled, the Android serial console
683     // spawns on a virtio-console port. If the bootloader is enabled, virtio
684     // console can't be used since uboot doesn't support it.
685     console_dev = "hvc1";
686   } else {
687     // crosvm ARM does not support ttyAMA. ttyAMA is a part of ARM arch.
688     Arch target = target_arch();
689     if ((target == Arch::Arm64 || target == Arch::Arm) &&
690         vm_manager() != vm_manager::CrosvmManager::name()) {
691       console_dev = "ttyAMA0";
692     } else {
693       console_dev = "ttyS0";
694     }
695   }
696   return console_dev;
697 }
698 
699 static constexpr char kVhostNet[] = "vhost_net";
set_vhost_net(bool vhost_net)700 void CuttlefishConfig::set_vhost_net(bool vhost_net) {
701   (*dictionary_)[kVhostNet] = vhost_net;
702 }
vhost_net() const703 bool CuttlefishConfig::vhost_net() const {
704   return (*dictionary_)[kVhostNet].asBool();
705 }
706 
707 static constexpr char kVhostUserMac80211Hwsim[] = "vhost_user_mac80211_hwsim";
set_vhost_user_mac80211_hwsim(const std::string & path)708 void CuttlefishConfig::set_vhost_user_mac80211_hwsim(const std::string& path) {
709   (*dictionary_)[kVhostUserMac80211Hwsim] = path;
710 }
vhost_user_mac80211_hwsim() const711 std::string CuttlefishConfig::vhost_user_mac80211_hwsim() const {
712   return (*dictionary_)[kVhostUserMac80211Hwsim].asString();
713 }
714 
715 static constexpr char kWmediumdApiServerSocket[] = "wmediumd_api_server_socket";
set_wmediumd_api_server_socket(const std::string & path)716 void CuttlefishConfig::set_wmediumd_api_server_socket(const std::string& path) {
717   (*dictionary_)[kWmediumdApiServerSocket] = path;
718 }
wmediumd_api_server_socket() const719 std::string CuttlefishConfig::wmediumd_api_server_socket() const {
720   return (*dictionary_)[kWmediumdApiServerSocket].asString();
721 }
722 
723 static constexpr char kApRootfsImage[] = "ap_rootfs_image";
ap_rootfs_image() const724 std::string CuttlefishConfig::ap_rootfs_image() const {
725   return (*dictionary_)[kApRootfsImage].asString();
726 }
set_ap_rootfs_image(const std::string & ap_rootfs_image)727 void CuttlefishConfig::set_ap_rootfs_image(const std::string& ap_rootfs_image) {
728   (*dictionary_)[kApRootfsImage] = ap_rootfs_image;
729 }
730 
731 static constexpr char kApKernelImage[] = "ap_kernel_image";
ap_kernel_image() const732 std::string CuttlefishConfig::ap_kernel_image() const {
733   return (*dictionary_)[kApKernelImage].asString();
734 }
set_ap_kernel_image(const std::string & ap_kernel_image)735 void CuttlefishConfig::set_ap_kernel_image(const std::string& ap_kernel_image) {
736   (*dictionary_)[kApKernelImage] = ap_kernel_image;
737 }
738 
739 static constexpr char kWmediumdConfig[] = "wmediumd_config";
set_wmediumd_config(const std::string & config)740 void CuttlefishConfig::set_wmediumd_config(const std::string& config) {
741   (*dictionary_)[kWmediumdConfig] = config;
742 }
wmediumd_config() const743 std::string CuttlefishConfig::wmediumd_config() const {
744   return (*dictionary_)[kWmediumdConfig].asString();
745 }
746 
747 static constexpr char kRootcanalHciPort[] = "rootcanal_hci_port";
rootcanal_hci_port() const748 int CuttlefishConfig::rootcanal_hci_port() const {
749   return (*dictionary_)[kRootcanalHciPort].asInt();
750 }
set_rootcanal_hci_port(int rootcanal_hci_port)751 void CuttlefishConfig::set_rootcanal_hci_port(int rootcanal_hci_port) {
752   (*dictionary_)[kRootcanalHciPort] = rootcanal_hci_port;
753 }
754 
755 static constexpr char kRootcanalLinkPort[] = "rootcanal_link_port";
rootcanal_link_port() const756 int CuttlefishConfig::rootcanal_link_port() const {
757   return (*dictionary_)[kRootcanalLinkPort].asInt();
758 }
set_rootcanal_link_port(int rootcanal_link_port)759 void CuttlefishConfig::set_rootcanal_link_port(int rootcanal_link_port) {
760   (*dictionary_)[kRootcanalLinkPort] = rootcanal_link_port;
761 }
762 
763 static constexpr char kRootcanalTestPort[] = "rootcanal_test_port";
rootcanal_test_port() const764 int CuttlefishConfig::rootcanal_test_port() const {
765   return (*dictionary_)[kRootcanalTestPort].asInt();
766 }
set_rootcanal_test_port(int rootcanal_test_port)767 void CuttlefishConfig::set_rootcanal_test_port(int rootcanal_test_port) {
768   (*dictionary_)[kRootcanalTestPort] = rootcanal_test_port;
769 }
770 
771 static constexpr char kRootcanalConfigFile[] = "rootcanal_config_file";
rootcanal_config_file() const772 std::string CuttlefishConfig::rootcanal_config_file() const {
773   return (*dictionary_)[kRootcanalConfigFile].asString();
774 }
set_rootcanal_config_file(const std::string & rootcanal_config_file)775 void CuttlefishConfig::set_rootcanal_config_file(
776     const std::string& rootcanal_config_file) {
777   (*dictionary_)[kRootcanalConfigFile] =
778       DefaultHostArtifactsPath(rootcanal_config_file);
779 }
780 
781 static constexpr char kRootcanalDefaultCommandsFile[] =
782     "rootcanal_default_commands_file";
rootcanal_default_commands_file() const783 std::string CuttlefishConfig::rootcanal_default_commands_file() const {
784   return (*dictionary_)[kRootcanalDefaultCommandsFile].asString();
785 }
set_rootcanal_default_commands_file(const std::string & rootcanal_default_commands_file)786 void CuttlefishConfig::set_rootcanal_default_commands_file(
787     const std::string& rootcanal_default_commands_file) {
788   (*dictionary_)[kRootcanalDefaultCommandsFile] =
789       DefaultHostArtifactsPath(rootcanal_default_commands_file);
790 }
791 
792 static constexpr char kRecordScreen[] = "record_screen";
set_record_screen(bool record_screen)793 void CuttlefishConfig::set_record_screen(bool record_screen) {
794   (*dictionary_)[kRecordScreen] = record_screen;
795 }
record_screen() const796 bool CuttlefishConfig::record_screen() const {
797   return (*dictionary_)[kRecordScreen].asBool();
798 }
799 
800 static constexpr char kSmt[] = "smt";
set_smt(bool smt)801 void CuttlefishConfig::set_smt(bool smt) {
802   (*dictionary_)[kSmt] = smt;
803 }
smt() const804 bool CuttlefishConfig::smt() const {
805   return (*dictionary_)[kSmt].asBool();
806 }
807 
808 static constexpr char kEnableAudio[] = "enable_audio";
set_enable_audio(bool enable)809 void CuttlefishConfig::set_enable_audio(bool enable) {
810   (*dictionary_)[kEnableAudio] = enable;
811 }
enable_audio() const812 bool CuttlefishConfig::enable_audio() const {
813   return (*dictionary_)[kEnableAudio].asBool();
814 }
815 
816 static constexpr char kProtectedVm[] = "protected_vm";
set_protected_vm(bool protected_vm)817 void CuttlefishConfig::set_protected_vm(bool protected_vm) {
818   (*dictionary_)[kProtectedVm] = protected_vm;
819 }
protected_vm() const820 bool CuttlefishConfig::protected_vm() const {
821   return (*dictionary_)[kProtectedVm].asBool();
822 }
823 
824 static constexpr char kTargetArch[] = "target_arch";
set_target_arch(Arch target_arch)825 void CuttlefishConfig::set_target_arch(Arch target_arch) {
826   (*dictionary_)[kTargetArch] = static_cast<int>(target_arch);
827 }
target_arch() const828 Arch CuttlefishConfig::target_arch() const {
829   return static_cast<Arch>((*dictionary_)[kTargetArch].asInt());
830 }
831 
832 static constexpr char kBootconfigSupported[] = "bootconfig_supported";
bootconfig_supported() const833 bool CuttlefishConfig::bootconfig_supported() const {
834   return (*dictionary_)[kBootconfigSupported].asBool();
835 }
set_bootconfig_supported(bool bootconfig_supported)836 void CuttlefishConfig::set_bootconfig_supported(bool bootconfig_supported) {
837   (*dictionary_)[kBootconfigSupported] = bootconfig_supported;
838 }
839 
840 static constexpr char kUserdataFormat[] = "userdata_format";
userdata_format() const841 std::string CuttlefishConfig::userdata_format() const {
842   return (*dictionary_)[kUserdataFormat].asString();
843 }
set_userdata_format(const std::string & userdata_format)844 void CuttlefishConfig::set_userdata_format(const std::string& userdata_format) {
845   auto fmt = userdata_format;
846   std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::tolower);
847   (*dictionary_)[kUserdataFormat] = fmt;
848 }
849 
850 static constexpr char kApImageDevPath[] = "ap_image_dev_path";
ap_image_dev_path() const851 std::string CuttlefishConfig::ap_image_dev_path() const {
852   return (*dictionary_)[kApImageDevPath].asString();
853 }
set_ap_image_dev_path(const std::string & dev_path)854 void CuttlefishConfig::set_ap_image_dev_path(const std::string& dev_path) {
855   (*dictionary_)[kApImageDevPath] = dev_path;
856 }
857 
BuildConfigImpl(const std::string & path)858 /*static*/ CuttlefishConfig* CuttlefishConfig::BuildConfigImpl(
859     const std::string& path) {
860   auto ret = new CuttlefishConfig();
861   if (ret) {
862     auto loaded = ret->LoadFromFile(path.c_str());
863     if (!loaded) {
864       delete ret;
865       return nullptr;
866     }
867   }
868   return ret;
869 }
870 
871 /*static*/ std::unique_ptr<const CuttlefishConfig>
GetFromFile(const std::string & path)872 CuttlefishConfig::GetFromFile(const std::string& path) {
873   return std::unique_ptr<const CuttlefishConfig>(BuildConfigImpl(path));
874 }
875 
876 // Creates the (initially empty) config object and populates it with values from
877 // the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
878 // Returns nullptr if there was an error loading from file
Get()879 /*static*/ const CuttlefishConfig* CuttlefishConfig::Get() {
880   auto config_file_path =
881       StringFromEnv(kCuttlefishConfigEnvVarName, GetGlobalConfigFileLink());
882   static std::shared_ptr<CuttlefishConfig> config(
883       BuildConfigImpl(config_file_path));
884   return config.get();
885 }
886 
ConfigExists()887 /*static*/ bool CuttlefishConfig::ConfigExists() {
888   auto config_file_path = StringFromEnv(kCuttlefishConfigEnvVarName,
889                                         GetGlobalConfigFileLink());
890   auto real_file_path = AbsolutePath(config_file_path.c_str());
891   return FileExists(real_file_path);
892 }
893 
CuttlefishConfig()894 CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {}
895 // Can't use '= default' on the header because the compiler complains of
896 // Json::Value being an incomplete type
897 CuttlefishConfig::~CuttlefishConfig() = default;
898 
899 CuttlefishConfig::CuttlefishConfig(CuttlefishConfig&&) = default;
900 CuttlefishConfig& CuttlefishConfig::operator=(CuttlefishConfig&&) = default;
901 
LoadFromFile(const char * file)902 bool CuttlefishConfig::LoadFromFile(const char* file) {
903   auto real_file_path = AbsolutePath(file);
904   if (real_file_path.empty()) {
905     LOG(ERROR) << "Could not get real path for file " << file;
906     return false;
907   }
908   Json::CharReaderBuilder builder;
909   std::ifstream ifs(real_file_path);
910   std::string errorMessage;
911   if (!Json::parseFromStream(builder, ifs, dictionary_.get(), &errorMessage)) {
912     LOG(ERROR) << "Could not read config file " << file << ": " << errorMessage;
913     return false;
914   }
915   return true;
916 }
SaveToFile(const std::string & file) const917 bool CuttlefishConfig::SaveToFile(const std::string& file) const {
918   std::ofstream ofs(file);
919   if (!ofs.is_open()) {
920     LOG(ERROR) << "Unable to write to file " << file;
921     return false;
922   }
923   ofs << *dictionary_;
924   return !ofs.fail();
925 }
926 
instances_dir() const927 std::string CuttlefishConfig::instances_dir() const {
928   return AbsolutePath(root_dir() + "/instances");
929 }
930 
InstancesPath(const std::string & file_name) const931 std::string CuttlefishConfig::InstancesPath(
932     const std::string& file_name) const {
933   return AbsolutePath(instances_dir() + "/" + file_name);
934 }
935 
assembly_dir() const936 std::string CuttlefishConfig::assembly_dir() const {
937   return AbsolutePath(root_dir() + "/assembly");
938 }
939 
AssemblyPath(const std::string & file_name) const940 std::string CuttlefishConfig::AssemblyPath(
941     const std::string& file_name) const {
942   return AbsolutePath(assembly_dir() + "/" + file_name);
943 }
944 
os_composite_disk_path() const945 std::string CuttlefishConfig::os_composite_disk_path() const {
946   return AssemblyPath("os_composite.img");
947 }
948 
ForInstance(int num)949 CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForInstance(int num) {
950   return MutableInstanceSpecific(this, std::to_string(num));
951 }
952 
ForInstance(int num) const953 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForInstance(int num) const {
954   return InstanceSpecific(this, std::to_string(num));
955 }
956 
ForInstanceName(const std::string & name) const957 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForInstanceName(
958     const std::string& name) const {
959   return ForInstance(InstanceFromString(name));
960 }
961 
ForDefaultInstance() const962 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForDefaultInstance() const {
963   return ForInstance(GetInstance());
964 }
965 
Instances() const966 std::vector<CuttlefishConfig::InstanceSpecific> CuttlefishConfig::Instances() const {
967   const auto& json = (*dictionary_)[kInstances];
968   std::vector<CuttlefishConfig::InstanceSpecific> instances;
969   for (const auto& name : json.getMemberNames()) {
970     instances.push_back(CuttlefishConfig::InstanceSpecific(this, name));
971   }
972   return instances;
973 }
974 
instance_dirs() const975 std::vector<std::string> CuttlefishConfig::instance_dirs() const {
976   std::vector<std::string> result;
977   for (const auto& instance : Instances()) {
978     result.push_back(instance.instance_dir());
979   }
980   return result;
981 }
982 
983 static constexpr char kInstanceNames[] = "instance_names";
set_instance_names(const std::vector<std::string> & instance_names)984 void CuttlefishConfig::set_instance_names(
985     const std::vector<std::string>& instance_names) {
986   Json::Value args_json_obj(Json::arrayValue);
987   for (const auto& name : instance_names) {
988     args_json_obj.append(name);
989   }
990   (*dictionary_)[kInstanceNames] = args_json_obj;
991 }
instance_names() const992 std::vector<std::string> CuttlefishConfig::instance_names() const {
993   // NOTE: The structure of this field needs to remain stable, since
994   // cvd_server may call this on config JSON files from various builds.
995   //
996   // This info is duplicated into its own field here so it is simpler
997   // to keep stable, rather than parsing from Instances()::instance_name.
998   //
999   // Any non-stable changes must be accompanied by an uprev to the
1000   // cvd_server major version.
1001   std::vector<std::string> names;
1002   for (const Json::Value& name : (*dictionary_)[kInstanceNames]) {
1003     names.push_back(name.asString());
1004   }
1005   return names;
1006 }
1007 
GetInstance()1008 int GetInstance() {
1009   static int instance_id = InstanceFromEnvironment();
1010   return instance_id;
1011 }
1012 
GetDefaultVsockCid()1013 int GetDefaultVsockCid() {
1014   // we assume that this function is used to configure CuttlefishConfig once
1015   static const int default_vsock_cid = 3 + GetInstance() - 1;
1016   return default_vsock_cid;
1017 }
1018 
GetVsockServerPort(const int base,const int vsock_guest_cid)1019 int GetVsockServerPort(const int base,
1020                        const int vsock_guest_cid /**< per instance guest cid */) {
1021     return base + (vsock_guest_cid - 3);
1022 }
1023 
GetGlobalConfigFileLink()1024 std::string GetGlobalConfigFileLink() {
1025   return StringFromEnv("HOME", ".") + "/.cuttlefish_config.json";
1026 }
1027 
ForCurrentInstance(const char * prefix)1028 std::string ForCurrentInstance(const char* prefix) {
1029   std::ostringstream stream;
1030   stream << prefix << std::setfill('0') << std::setw(2) << GetInstance();
1031   return stream.str();
1032 }
ForCurrentInstance(int base)1033 int ForCurrentInstance(int base) { return base + GetInstance() - 1; }
1034 
RandomSerialNumber(const std::string & prefix)1035 std::string RandomSerialNumber(const std::string& prefix) {
1036   const char hex_characters[] = "0123456789ABCDEF";
1037   std::srand(time(0));
1038   char str[10];
1039   for(int i=0; i<10; i++){
1040     str[i] = hex_characters[rand() % strlen(hex_characters)];
1041   }
1042   return prefix + str;
1043 }
1044 
DefaultHostArtifactsPath(const std::string & file_name)1045 std::string DefaultHostArtifactsPath(const std::string& file_name) {
1046   return (StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) + "/") +
1047          file_name;
1048 }
1049 
HostBinaryPath(const std::string & binary_name)1050 std::string HostBinaryPath(const std::string& binary_name) {
1051 #ifdef __ANDROID__
1052   return binary_name;
1053 #else
1054   return DefaultHostArtifactsPath("bin/" + binary_name);
1055 #endif
1056 }
1057 
DefaultGuestImagePath(const std::string & file_name)1058 std::string DefaultGuestImagePath(const std::string& file_name) {
1059   return (StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", "."))) +
1060          file_name;
1061 }
1062 
HostSupportsQemuCli()1063 bool HostSupportsQemuCli() {
1064   static bool supported =
1065       std::system(
1066           "/usr/lib/cuttlefish-common/bin/capability_query.py qemu_cli") == 0;
1067   return supported;
1068 }
1069 
1070 }  // namespace cuttlefish
1071