• 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/qemu_manager.h"
39 
40 namespace cuttlefish {
41 namespace {
42 
InstanceFromEnvironment()43 int InstanceFromEnvironment() {
44   static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE";
45   static constexpr int kDefaultInstance = 1;
46 
47   // CUTTLEFISH_INSTANCE environment variable
48   std::string instance_str = StringFromEnv(kInstanceEnvironmentVariable, "");
49   if (instance_str.empty()) {
50     // Try to get it from the user instead
51     instance_str = StringFromEnv("USER", "");
52 
53     if (instance_str.empty()) {
54       LOG(DEBUG) << "CUTTLEFISH_INSTANCE and USER unset, using instance id "
55                  << kDefaultInstance;
56       return kDefaultInstance;
57     }
58     if (!android::base::StartsWith(instance_str, kVsocUserPrefix)) {
59       // No user or we don't recognize this user
60       LOG(DEBUG) << "Non-vsoc user, using instance id " << kDefaultInstance;
61       return kDefaultInstance;
62     }
63     instance_str = instance_str.substr(std::string(kVsocUserPrefix).size());
64   }
65   int instance = std::stoi(instance_str);
66   if (instance <= 0) {
67     LOG(INFO) << "Failed to interpret \"" << instance_str << "\" as an id, "
68               << "using instance id " << kDefaultInstance;
69     return kDefaultInstance;
70   }
71   return instance;
72 }
73 
74 const char* kInstances = "instances";
75 
76 
77 }  // namespace
78 
79 const char* const kGpuModeAuto = "auto";
80 const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
81 const char* const kGpuModeDrmVirgl = "drm_virgl";
82 const char* const kGpuModeGfxStream = "gfxstream";
83 
DefaultEnvironmentPath(const char * environment_key,const char * default_value,const char * subpath)84 std::string DefaultEnvironmentPath(const char* environment_key,
85                                    const char* default_value,
86                                    const char* subpath) {
87   return StringFromEnv(environment_key, default_value) + "/" + subpath;
88 }
89 
90 static constexpr char kAssemblyDir[] = "assembly_dir";
assembly_dir() const91 std::string CuttlefishConfig::assembly_dir() const {
92   return (*dictionary_)[kAssemblyDir].asString();
93 }
set_assembly_dir(const std::string & assembly_dir)94 void CuttlefishConfig::set_assembly_dir(const std::string& assembly_dir) {
95   (*dictionary_)[kAssemblyDir] = assembly_dir;
96 }
97 
98 static constexpr char kVmManager[] = "vm_manager";
vm_manager() const99 std::string CuttlefishConfig::vm_manager() const {
100   return (*dictionary_)[kVmManager].asString();
101 }
set_vm_manager(const std::string & name)102 void CuttlefishConfig::set_vm_manager(const std::string& name) {
103   (*dictionary_)[kVmManager] = name;
104 }
105 
106 static constexpr char kGpuMode[] = "gpu_mode";
gpu_mode() const107 std::string CuttlefishConfig::gpu_mode() const {
108   return (*dictionary_)[kGpuMode].asString();
109 }
set_gpu_mode(const std::string & name)110 void CuttlefishConfig::set_gpu_mode(const std::string& name) {
111   (*dictionary_)[kGpuMode] = name;
112 }
113 
114 static constexpr char kCpus[] = "cpus";
cpus() const115 int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); }
set_cpus(int cpus)116 void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; }
117 
118 static constexpr char kMemoryMb[] = "memory_mb";
memory_mb() const119 int CuttlefishConfig::memory_mb() const {
120   return (*dictionary_)[kMemoryMb].asInt();
121 }
set_memory_mb(int memory_mb)122 void CuttlefishConfig::set_memory_mb(int memory_mb) {
123   (*dictionary_)[kMemoryMb] = memory_mb;
124 }
125 
126 static constexpr char kDpi[] = "dpi";
dpi() const127 int CuttlefishConfig::dpi() const { return (*dictionary_)[kDpi].asInt(); }
set_dpi(int dpi)128 void CuttlefishConfig::set_dpi(int dpi) { (*dictionary_)[kDpi] = dpi; }
129 
130 static constexpr char kDisplayConfigs[] = "display_configs";
131 static constexpr char kXRes[] = "x_res";
132 static constexpr char kYRes[] = "y_res";
133 std::vector<CuttlefishConfig::DisplayConfig>
display_configs() const134 CuttlefishConfig::display_configs() const {
135   std::vector<DisplayConfig> display_configs;
136   for (auto& display_config_json : (*dictionary_)[kDisplayConfigs]) {
137     DisplayConfig display_config = {};
138     display_config.width = display_config_json[kXRes].asInt();
139     display_config.height = display_config_json[kYRes].asInt();
140     display_configs.emplace_back(std::move(display_config));
141   }
142   return display_configs;
143 }
set_display_configs(const std::vector<DisplayConfig> & display_configs)144 void CuttlefishConfig::set_display_configs(
145     const std::vector<DisplayConfig>& display_configs) {
146   Json::Value display_configs_json(Json::arrayValue);
147 
148   for (const DisplayConfig& display_configs : display_configs) {
149     Json::Value display_config_json(Json::objectValue);
150     display_config_json[kXRes] = display_configs.width;
151     display_config_json[kYRes] = display_configs.height;
152     display_configs_json.append(display_config_json);
153   }
154 
155   (*dictionary_)[kDisplayConfigs] = display_configs_json;
156 }
157 
158 static constexpr char kRefreshRateHz[] = "refresh_rate_hz";
refresh_rate_hz() const159 int CuttlefishConfig::refresh_rate_hz() const {
160   return (*dictionary_)[kRefreshRateHz].asInt();
161 }
set_refresh_rate_hz(int refresh_rate_hz)162 void CuttlefishConfig::set_refresh_rate_hz(int refresh_rate_hz) {
163   (*dictionary_)[kRefreshRateHz] = refresh_rate_hz;
164 }
165 
SetPath(const std::string & key,const std::string & path)166 void CuttlefishConfig::SetPath(const std::string& key,
167                                const std::string& path) {
168   if (!path.empty()) {
169     (*dictionary_)[key] = AbsolutePath(path);
170   }
171 }
172 
173 static constexpr char kGdbPort[] = "gdb_port";
gdb_port() const174 int CuttlefishConfig::gdb_port() const {
175   return (*dictionary_)[kGdbPort].asInt();
176 }
set_gdb_port(int port)177 void CuttlefishConfig::set_gdb_port(int port) {
178   (*dictionary_)[kGdbPort] = port;
179 }
180 
181 static constexpr char kDeprecatedBootCompleted[] = "deprecated_boot_completed";
deprecated_boot_completed() const182 bool CuttlefishConfig::deprecated_boot_completed() const {
183   return (*dictionary_)[kDeprecatedBootCompleted].asBool();
184 }
set_deprecated_boot_completed(bool deprecated_boot_completed)185 void CuttlefishConfig::set_deprecated_boot_completed(
186     bool deprecated_boot_completed) {
187   (*dictionary_)[kDeprecatedBootCompleted] = deprecated_boot_completed;
188 }
189 
190 static constexpr char kCuttlefishEnvPath[] = "cuttlefish_env_path";
set_cuttlefish_env_path(const std::string & path)191 void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) {
192   SetPath(kCuttlefishEnvPath, path);
193 }
cuttlefish_env_path() const194 std::string CuttlefishConfig::cuttlefish_env_path() const {
195   return (*dictionary_)[kCuttlefishEnvPath].asString();
196 }
197 
stringToAdbMode(std::string mode)198 static AdbMode stringToAdbMode(std::string mode) {
199   std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
200   if (mode == "vsock_tunnel") {
201     return AdbMode::VsockTunnel;
202   } else if (mode == "vsock_half_tunnel") {
203     return AdbMode::VsockHalfTunnel;
204   } else if (mode == "native_vsock") {
205     return AdbMode::NativeVsock;
206   } else {
207     return AdbMode::Unknown;
208   }
209 }
210 
211 static constexpr char kAdbMode[] = "adb_mode";
adb_mode() const212 std::set<AdbMode> CuttlefishConfig::adb_mode() const {
213   std::set<AdbMode> args_set;
214   for (auto& mode : (*dictionary_)[kAdbMode]) {
215     args_set.insert(stringToAdbMode(mode.asString()));
216   }
217   return args_set;
218 }
set_adb_mode(const std::set<std::string> & mode)219 void CuttlefishConfig::set_adb_mode(const std::set<std::string>& mode) {
220   Json::Value mode_json_obj(Json::arrayValue);
221   for (const auto& arg : mode) {
222     mode_json_obj.append(arg);
223   }
224   (*dictionary_)[kAdbMode] = mode_json_obj;
225 }
226 
StringToSecureHal(std::string mode)227 static SecureHal StringToSecureHal(std::string mode) {
228   std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
229   if (mode == "keymint") {
230     return SecureHal::Keymint;
231   } else if (mode == "gatekeeper") {
232     return SecureHal::Gatekeeper;
233   } else {
234     return SecureHal::Unknown;
235   }
236 }
237 
238 static constexpr char kSecureHals[] = "secure_hals";
secure_hals() const239 std::set<SecureHal> CuttlefishConfig::secure_hals() const {
240   std::set<SecureHal> args_set;
241   for (auto& hal : (*dictionary_)[kSecureHals]) {
242     args_set.insert(StringToSecureHal(hal.asString()));
243   }
244   return args_set;
245 }
set_secure_hals(const std::set<std::string> & hals)246 void CuttlefishConfig::set_secure_hals(const std::set<std::string>& hals) {
247   Json::Value hals_json_obj(Json::arrayValue);
248   for (const auto& hal : hals) {
249     hals_json_obj.append(hal);
250   }
251   (*dictionary_)[kSecureHals] = hals_json_obj;
252 }
253 
254 static constexpr char kSetupWizardMode[] = "setupwizard_mode";
setupwizard_mode() const255 std::string CuttlefishConfig::setupwizard_mode() const {
256   return (*dictionary_)[kSetupWizardMode].asString();
257 }
set_setupwizard_mode(const std::string & mode)258 void CuttlefishConfig::set_setupwizard_mode(const std::string& mode) {
259   (*dictionary_)[kSetupWizardMode] = mode;
260 }
261 
262 static constexpr char kQemuBinaryDir[] = "qemu_binary_dir";
qemu_binary_dir() const263 std::string CuttlefishConfig::qemu_binary_dir() const {
264   return (*dictionary_)[kQemuBinaryDir].asString();
265 }
set_qemu_binary_dir(const std::string & qemu_binary_dir)266 void CuttlefishConfig::set_qemu_binary_dir(const std::string& qemu_binary_dir) {
267   (*dictionary_)[kQemuBinaryDir] = qemu_binary_dir;
268 }
269 
270 static constexpr char kCrosvmBinary[] = "crosvm_binary";
crosvm_binary() const271 std::string CuttlefishConfig::crosvm_binary() const {
272   return (*dictionary_)[kCrosvmBinary].asString();
273 }
set_crosvm_binary(const std::string & crosvm_binary)274 void CuttlefishConfig::set_crosvm_binary(const std::string& crosvm_binary) {
275   (*dictionary_)[kCrosvmBinary] = crosvm_binary;
276 }
277 
278 static constexpr char kTpmDevice[] = "tpm_device";
tpm_device() const279 std::string CuttlefishConfig::tpm_device() const {
280   return (*dictionary_)[kTpmDevice].asString();
281 }
set_tpm_device(const std::string & tpm_device)282 void CuttlefishConfig::set_tpm_device(const std::string& tpm_device) {
283   (*dictionary_)[kTpmDevice] = tpm_device;
284 }
285 
286 static constexpr char kEnableGnssGrpcProxy[] = "enable_gnss_grpc_proxy";
set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy)287 void CuttlefishConfig::set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy) {
288   (*dictionary_)[kEnableGnssGrpcProxy] = enable_gnss_grpc_proxy;
289 }
enable_gnss_grpc_proxy() const290 bool CuttlefishConfig::enable_gnss_grpc_proxy() const {
291   return (*dictionary_)[kEnableGnssGrpcProxy].asBool();
292 }
293 
294 static constexpr char kEnableVncServer[] = "enable_vnc_server";
enable_vnc_server() const295 bool CuttlefishConfig::enable_vnc_server() const {
296   return (*dictionary_)[kEnableVncServer].asBool();
297 }
set_enable_vnc_server(bool enable_vnc_server)298 void CuttlefishConfig::set_enable_vnc_server(bool enable_vnc_server) {
299   (*dictionary_)[kEnableVncServer] = enable_vnc_server;
300 }
301 
302 static constexpr char kEnableSandbox[] = "enable_sandbox";
set_enable_sandbox(const bool enable_sandbox)303 void CuttlefishConfig::set_enable_sandbox(const bool enable_sandbox) {
304   (*dictionary_)[kEnableSandbox] = enable_sandbox;
305 }
enable_sandbox() const306 bool CuttlefishConfig::enable_sandbox() const {
307   return (*dictionary_)[kEnableSandbox].asBool();
308 }
309 
310 static constexpr char kSeccompPolicyDir[] = "seccomp_policy_dir";
set_seccomp_policy_dir(const std::string & seccomp_policy_dir)311 void CuttlefishConfig::set_seccomp_policy_dir(const std::string& seccomp_policy_dir) {
312   if (seccomp_policy_dir.empty()) {
313     (*dictionary_)[kSeccompPolicyDir] = seccomp_policy_dir;
314     return;
315   }
316   SetPath(kSeccompPolicyDir, seccomp_policy_dir);
317 }
seccomp_policy_dir() const318 std::string CuttlefishConfig::seccomp_policy_dir() const {
319   return (*dictionary_)[kSeccompPolicyDir].asString();
320 }
321 
322 static constexpr char kEnableWebRTC[] = "enable_webrtc";
set_enable_webrtc(bool enable_webrtc)323 void CuttlefishConfig::set_enable_webrtc(bool enable_webrtc) {
324   (*dictionary_)[kEnableWebRTC] = enable_webrtc;
325 }
enable_webrtc() const326 bool CuttlefishConfig::enable_webrtc() const {
327   return (*dictionary_)[kEnableWebRTC].asBool();
328 }
329 
330 static constexpr char kEnableVehicleHalServer[] = "enable_vehicle_hal_server";
set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server)331 void CuttlefishConfig::set_enable_vehicle_hal_grpc_server(bool enable_vehicle_hal_grpc_server) {
332   (*dictionary_)[kEnableVehicleHalServer] = enable_vehicle_hal_grpc_server;
333 }
enable_vehicle_hal_grpc_server() const334 bool CuttlefishConfig::enable_vehicle_hal_grpc_server() const {
335   return (*dictionary_)[kEnableVehicleHalServer].asBool();
336 }
337 
338 static constexpr char kVehicleHalServerBinary[] = "vehicle_hal_server_binary";
set_vehicle_hal_grpc_server_binary(const std::string & vehicle_hal_server_binary)339 void CuttlefishConfig::set_vehicle_hal_grpc_server_binary(const std::string& vehicle_hal_server_binary) {
340   (*dictionary_)[kVehicleHalServerBinary] = vehicle_hal_server_binary;
341 }
vehicle_hal_grpc_server_binary() const342 std::string CuttlefishConfig::vehicle_hal_grpc_server_binary() const {
343   return (*dictionary_)[kVehicleHalServerBinary].asString();
344 }
345 
346 static constexpr char kCustomActions[] = "custom_actions";
set_custom_actions(const std::vector<CustomActionConfig> & actions)347 void CuttlefishConfig::set_custom_actions(const std::vector<CustomActionConfig>& actions) {
348   Json::Value actions_array(Json::arrayValue);
349   for (const auto& action : actions) {
350     actions_array.append(action.ToJson());
351   }
352   (*dictionary_)[kCustomActions] = actions_array;
353 }
custom_actions() const354 std::vector<CustomActionConfig> CuttlefishConfig::custom_actions() const {
355   std::vector<CustomActionConfig> result;
356   for (Json::Value custom_action : (*dictionary_)[kCustomActions]) {
357     result.push_back(CustomActionConfig(custom_action));
358   }
359   return result;
360 }
361 
362 static constexpr char kWebRTCAssetsDir[] = "webrtc_assets_dir";
set_webrtc_assets_dir(const std::string & webrtc_assets_dir)363 void CuttlefishConfig::set_webrtc_assets_dir(const std::string& webrtc_assets_dir) {
364   (*dictionary_)[kWebRTCAssetsDir] = webrtc_assets_dir;
365 }
webrtc_assets_dir() const366 std::string CuttlefishConfig::webrtc_assets_dir() const {
367   return (*dictionary_)[kWebRTCAssetsDir].asString();
368 }
369 
370 static constexpr char kWebRTCEnableADBWebSocket[] =
371     "webrtc_enable_adb_websocket";
set_webrtc_enable_adb_websocket(bool enable)372 void CuttlefishConfig::set_webrtc_enable_adb_websocket(bool enable) {
373     (*dictionary_)[kWebRTCEnableADBWebSocket] = enable;
374 }
webrtc_enable_adb_websocket() const375 bool CuttlefishConfig::webrtc_enable_adb_websocket() const {
376     return (*dictionary_)[kWebRTCEnableADBWebSocket].asBool();
377 }
378 
379 static constexpr char kRestartSubprocesses[] = "restart_subprocesses";
restart_subprocesses() const380 bool CuttlefishConfig::restart_subprocesses() const {
381   return (*dictionary_)[kRestartSubprocesses].asBool();
382 }
set_restart_subprocesses(bool restart_subprocesses)383 void CuttlefishConfig::set_restart_subprocesses(bool restart_subprocesses) {
384   (*dictionary_)[kRestartSubprocesses] = restart_subprocesses;
385 }
386 
387 static constexpr char kRunAdbConnector[] = "run_adb_connector";
run_adb_connector() const388 bool CuttlefishConfig::run_adb_connector() const {
389   return (*dictionary_)[kRunAdbConnector].asBool();
390 }
set_run_adb_connector(bool run_adb_connector)391 void CuttlefishConfig::set_run_adb_connector(bool run_adb_connector) {
392   (*dictionary_)[kRunAdbConnector] = run_adb_connector;
393 }
394 
395 static constexpr char kRunAsDaemon[] = "run_as_daemon";
run_as_daemon() const396 bool CuttlefishConfig::run_as_daemon() const {
397   return (*dictionary_)[kRunAsDaemon].asBool();
398 }
set_run_as_daemon(bool run_as_daemon)399 void CuttlefishConfig::set_run_as_daemon(bool run_as_daemon) {
400   (*dictionary_)[kRunAsDaemon] = run_as_daemon;
401 }
402 
403 static constexpr char kDataPolicy[] = "data_policy";
data_policy() const404 std::string CuttlefishConfig::data_policy() const {
405   return (*dictionary_)[kDataPolicy].asString();
406 }
set_data_policy(const std::string & data_policy)407 void CuttlefishConfig::set_data_policy(const std::string& data_policy) {
408   (*dictionary_)[kDataPolicy] = data_policy;
409 }
410 
411 static constexpr char kBlankDataImageMb[] = "blank_data_image_mb";
blank_data_image_mb() const412 int CuttlefishConfig::blank_data_image_mb() const {
413   return (*dictionary_)[kBlankDataImageMb].asInt();
414 }
set_blank_data_image_mb(int blank_data_image_mb)415 void CuttlefishConfig::set_blank_data_image_mb(int blank_data_image_mb) {
416   (*dictionary_)[kBlankDataImageMb] = blank_data_image_mb;
417 }
418 
419 static constexpr char kBlankDataImageFmt[] = "blank_data_image_fmt";
blank_data_image_fmt() const420 std::string CuttlefishConfig::blank_data_image_fmt() const {
421   return (*dictionary_)[kBlankDataImageFmt].asString();
422 }
set_blank_data_image_fmt(const std::string & blank_data_image_fmt)423 void CuttlefishConfig::set_blank_data_image_fmt(const std::string& blank_data_image_fmt) {
424   (*dictionary_)[kBlankDataImageFmt] = blank_data_image_fmt;
425 }
426 
427 static constexpr char kBootloader[] = "bootloader";
bootloader() const428 std::string CuttlefishConfig::bootloader() const {
429   return (*dictionary_)[kBootloader].asString();
430 }
set_bootloader(const std::string & bootloader)431 void CuttlefishConfig::set_bootloader(const std::string& bootloader) {
432   SetPath(kBootloader, bootloader);
433 }
434 
435 static constexpr char kBootSlot[] = "boot_slot";
set_boot_slot(const std::string & boot_slot)436 void CuttlefishConfig::set_boot_slot(const std::string& boot_slot) {
437   (*dictionary_)[kBootSlot] = boot_slot;
438 }
boot_slot() const439 std::string CuttlefishConfig::boot_slot() const {
440   return (*dictionary_)[kBootSlot].asString();
441 }
442 
443 static constexpr char kWebRTCCertsDir[] = "webrtc_certs_dir";
set_webrtc_certs_dir(const std::string & certs_dir)444 void CuttlefishConfig::set_webrtc_certs_dir(const std::string& certs_dir) {
445   (*dictionary_)[kWebRTCCertsDir] = certs_dir;
446 }
webrtc_certs_dir() const447 std::string CuttlefishConfig::webrtc_certs_dir() const {
448   return (*dictionary_)[kWebRTCCertsDir].asString();
449 }
450 
451 static constexpr char kSigServerPort[] = "webrtc_sig_server_port";
set_sig_server_port(int port)452 void CuttlefishConfig::set_sig_server_port(int port) {
453   (*dictionary_)[kSigServerPort] = port;
454 }
sig_server_port() const455 int CuttlefishConfig::sig_server_port() const {
456   return (*dictionary_)[kSigServerPort].asInt();
457 }
458 
459 static constexpr char kWebrtcUdpPortRange[] = "webrtc_udp_port_range";
set_webrtc_udp_port_range(std::pair<uint16_t,uint16_t> range)460 void CuttlefishConfig::set_webrtc_udp_port_range(
461     std::pair<uint16_t, uint16_t> range) {
462   Json::Value arr(Json::ValueType::arrayValue);
463   arr[0] = range.first;
464   arr[1] = range.second;
465   (*dictionary_)[kWebrtcUdpPortRange] = arr;
466 }
webrtc_udp_port_range() const467 std::pair<uint16_t, uint16_t> CuttlefishConfig::webrtc_udp_port_range() const {
468   std::pair<uint16_t, uint16_t> ret;
469   ret.first = (*dictionary_)[kWebrtcUdpPortRange][0].asInt();
470   ret.second = (*dictionary_)[kWebrtcUdpPortRange][1].asInt();
471   return ret;
472 }
473 
474 static constexpr char kWebrtcTcpPortRange[] = "webrtc_tcp_port_range";
set_webrtc_tcp_port_range(std::pair<uint16_t,uint16_t> range)475 void CuttlefishConfig::set_webrtc_tcp_port_range(
476     std::pair<uint16_t, uint16_t> range) {
477   Json::Value arr(Json::ValueType::arrayValue);
478   arr[0] = range.first;
479   arr[1] = range.second;
480   (*dictionary_)[kWebrtcTcpPortRange] = arr;
481 }
webrtc_tcp_port_range() const482 std::pair<uint16_t, uint16_t> CuttlefishConfig::webrtc_tcp_port_range() const {
483   std::pair<uint16_t, uint16_t> ret;
484   ret.first = (*dictionary_)[kWebrtcTcpPortRange][0].asInt();
485   ret.second = (*dictionary_)[kWebrtcTcpPortRange][1].asInt();
486   return ret;
487 }
488 
489 static constexpr char kSigServerAddress[] = "webrtc_sig_server_addr";
set_sig_server_address(const std::string & addr)490 void CuttlefishConfig::set_sig_server_address(const std::string& addr) {
491   (*dictionary_)[kSigServerAddress] = addr;
492 }
sig_server_address() const493 std::string CuttlefishConfig::sig_server_address() const {
494   return (*dictionary_)[kSigServerAddress].asString();
495 }
496 
497 static constexpr char kSigServerPath[] = "webrtc_sig_server_path";
set_sig_server_path(const std::string & path)498 void CuttlefishConfig::set_sig_server_path(const std::string& path) {
499   // Don't use SetPath here, it's a URL path not a file system path
500   (*dictionary_)[kSigServerPath] = path;
501 }
sig_server_path() const502 std::string CuttlefishConfig::sig_server_path() const {
503   return (*dictionary_)[kSigServerPath].asString();
504 }
505 
506 static constexpr char kSigServerStrict[] = "webrtc_sig_server_strict";
set_sig_server_strict(bool strict)507 void CuttlefishConfig::set_sig_server_strict(bool strict) {
508   (*dictionary_)[kSigServerStrict] = strict;
509 }
sig_server_strict() const510 bool CuttlefishConfig::sig_server_strict() const {
511   return (*dictionary_)[kSigServerStrict].asBool();
512 }
513 
514 static constexpr char kSigServerHeadersPath[] =
515     "webrtc_sig_server_headers_path";
set_sig_server_headers_path(const std::string & path)516 void CuttlefishConfig::set_sig_server_headers_path(const std::string& path) {
517   SetPath(kSigServerHeadersPath, path);
518 }
sig_server_headers_path() const519 std::string CuttlefishConfig::sig_server_headers_path() const {
520   return (*dictionary_)[kSigServerHeadersPath].asString();
521 }
522 
523 static constexpr char kRunModemSimulator[] = "enable_modem_simulator";
enable_modem_simulator() const524 bool CuttlefishConfig::enable_modem_simulator() const {
525   return (*dictionary_)[kRunModemSimulator].asBool();
526 }
set_enable_modem_simulator(bool enable_modem_simulator)527 void CuttlefishConfig::set_enable_modem_simulator(bool enable_modem_simulator) {
528   (*dictionary_)[kRunModemSimulator] = enable_modem_simulator;
529 }
530 
531 static constexpr char kModemSimulatorInstanceNumber[] =
532     "modem_simulator_instance_number";
set_modem_simulator_instance_number(int instance_number)533 void CuttlefishConfig::set_modem_simulator_instance_number(
534     int instance_number) {
535   (*dictionary_)[kModemSimulatorInstanceNumber] = instance_number;
536 }
modem_simulator_instance_number() const537 int CuttlefishConfig::modem_simulator_instance_number() const {
538   return (*dictionary_)[kModemSimulatorInstanceNumber].asInt();
539 }
540 
541 static constexpr char kModemSimulatorSimType[] = "modem_simulator_sim_type";
set_modem_simulator_sim_type(int sim_type)542 void CuttlefishConfig::set_modem_simulator_sim_type(int sim_type) {
543   (*dictionary_)[kModemSimulatorSimType] = sim_type;
544 }
modem_simulator_sim_type() const545 int CuttlefishConfig::modem_simulator_sim_type() const {
546   return (*dictionary_)[kModemSimulatorSimType].asInt();
547 }
548 
549 static constexpr char kHostToolsVersion[] = "host_tools_version";
set_host_tools_version(const std::map<std::string,uint32_t> & versions)550 void CuttlefishConfig::set_host_tools_version(
551     const std::map<std::string, uint32_t>& versions) {
552   Json::Value json(Json::objectValue);
553   for (const auto& [key, value] : versions) {
554     json[key] = value;
555   }
556   (*dictionary_)[kHostToolsVersion] = json;
557 }
host_tools_version() const558 std::map<std::string, uint32_t> CuttlefishConfig::host_tools_version() const {
559   if (!dictionary_->isMember(kHostToolsVersion)) {
560     return {};
561   }
562   std::map<std::string, uint32_t> versions;
563   const auto& elem = (*dictionary_)[kHostToolsVersion];
564   for (auto it = elem.begin(); it != elem.end(); it++) {
565     versions[it.key().asString()] = it->asUInt();
566   }
567   return versions;
568 }
569 
570 static constexpr char kGuestEnforceSecurity[] = "guest_enforce_security";
set_guest_enforce_security(bool guest_enforce_security)571 void CuttlefishConfig::set_guest_enforce_security(bool guest_enforce_security) {
572   (*dictionary_)[kGuestEnforceSecurity] = guest_enforce_security;
573 }
guest_enforce_security() const574 bool CuttlefishConfig::guest_enforce_security() const {
575   return (*dictionary_)[kGuestEnforceSecurity].asBool();
576 }
577 
578 const char* kGuestAuditSecurity = "guest_audit_security";
set_guest_audit_security(bool guest_audit_security)579 void CuttlefishConfig::set_guest_audit_security(bool guest_audit_security) {
580   (*dictionary_)[kGuestAuditSecurity] = guest_audit_security;
581 }
guest_audit_security() const582 bool CuttlefishConfig::guest_audit_security() const {
583   return (*dictionary_)[kGuestAuditSecurity].asBool();
584 }
585 
586 static constexpr char kenableHostBluetooth[] = "enable_host_bluetooth";
set_enable_host_bluetooth(bool enable_host_bluetooth)587 void CuttlefishConfig::set_enable_host_bluetooth(bool enable_host_bluetooth) {
588   (*dictionary_)[kenableHostBluetooth] = enable_host_bluetooth;
589 }
enable_host_bluetooth() const590 bool CuttlefishConfig::enable_host_bluetooth() const {
591   return (*dictionary_)[kenableHostBluetooth].asBool();
592 }
593 
594 static constexpr char kEnableMetrics[] = "enable_metrics";
set_enable_metrics(std::string enable_metrics)595 void CuttlefishConfig::set_enable_metrics(std::string enable_metrics) {
596   (*dictionary_)[kEnableMetrics] = kUnknown;
597   if (!enable_metrics.empty()) {
598     switch (enable_metrics.at(0)) {
599       case 'y':
600       case 'Y':
601         (*dictionary_)[kEnableMetrics] = kYes;
602         break;
603       case 'n':
604       case 'N':
605         (*dictionary_)[kEnableMetrics] = kNo;
606         break;
607     }
608   }
609 }
enable_metrics() const610 CuttlefishConfig::Answer CuttlefishConfig::enable_metrics() const {
611   return (CuttlefishConfig::Answer)(*dictionary_)[kEnableMetrics].asInt();
612 }
613 
614 static constexpr char kMetricsBinary[] = "metrics_binary";
set_metrics_binary(const std::string & metrics_binary)615 void CuttlefishConfig::set_metrics_binary(const std::string& metrics_binary) {
616   (*dictionary_)[kMetricsBinary] = metrics_binary;
617 }
metrics_binary() const618 std::string CuttlefishConfig::metrics_binary() const {
619   return (*dictionary_)[kMetricsBinary].asString();
620 }
621 
622 static constexpr char kExtraKernelCmdline[] = "extra_kernel_cmdline";
set_extra_kernel_cmdline(std::string extra_cmdline)623 void CuttlefishConfig::set_extra_kernel_cmdline(std::string extra_cmdline) {
624   Json::Value args_json_obj(Json::arrayValue);
625   for (const auto& arg : android::base::Split(extra_cmdline, " ")) {
626     args_json_obj.append(arg);
627   }
628   (*dictionary_)[kExtraKernelCmdline] = args_json_obj;
629 }
extra_kernel_cmdline() const630 std::vector<std::string> CuttlefishConfig::extra_kernel_cmdline() const {
631   std::vector<std::string> cmdline;
632   for (const Json::Value& arg : (*dictionary_)[kExtraKernelCmdline]) {
633     cmdline.push_back(arg.asString());
634   }
635   return cmdline;
636 }
637 
638 static constexpr char kRilDns[] = "ril_dns";
set_ril_dns(const std::string & ril_dns)639 void CuttlefishConfig::set_ril_dns(const std::string& ril_dns) {
640   (*dictionary_)[kRilDns] = ril_dns;
641 }
ril_dns() const642 std::string CuttlefishConfig::ril_dns() const {
643   return (*dictionary_)[kRilDns].asString();
644 }
645 
646 static constexpr char kKgdb[] = "kgdb";
set_kgdb(bool kgdb)647 void CuttlefishConfig::set_kgdb(bool kgdb) {
648   (*dictionary_)[kKgdb] = kgdb;
649 }
kgdb() const650 bool CuttlefishConfig::kgdb() const {
651   return (*dictionary_)[kKgdb].asBool();
652 }
653 
654 static constexpr char kEnableMinimalMode[] = "enable_minimal_mode";
enable_minimal_mode() const655 bool CuttlefishConfig::enable_minimal_mode() const {
656   return (*dictionary_)[kEnableMinimalMode].asBool();
657 }
set_enable_minimal_mode(bool enable_minimal_mode)658 void CuttlefishConfig::set_enable_minimal_mode(bool enable_minimal_mode) {
659   (*dictionary_)[kEnableMinimalMode] = enable_minimal_mode;
660 }
661 
662 static constexpr char kConsole[] = "console";
set_console(bool console)663 void CuttlefishConfig::set_console(bool console) {
664   (*dictionary_)[kConsole] = console;
665 }
console() const666 bool CuttlefishConfig::console() const {
667   return (*dictionary_)[kConsole].asBool();
668 }
console_dev() const669 std::string CuttlefishConfig::console_dev() const {
670   auto can_use_virtio_console = !kgdb() && !use_bootloader();
671   std::string console_dev;
672   if (can_use_virtio_console) {
673     // If kgdb and the bootloader are disabled, the Android serial console
674     // spawns on a virtio-console port. If the bootloader is enabled, virtio
675     // console can't be used since uboot doesn't support it.
676     console_dev = "hvc1";
677   } else {
678     // crosvm ARM does not support ttyAMA. ttyAMA is a part of ARM arch.
679     Arch target = target_arch();
680     if ((target == Arch::Arm64 || target == Arch::Arm) &&
681         vm_manager() != vm_manager::CrosvmManager::name()) {
682       console_dev = "ttyAMA0";
683     } else {
684       console_dev = "ttyS0";
685     }
686   }
687   return console_dev;
688 }
689 
690 static constexpr char kVhostNet[] = "vhost_net";
set_vhost_net(bool vhost_net)691 void CuttlefishConfig::set_vhost_net(bool vhost_net) {
692   (*dictionary_)[kVhostNet] = vhost_net;
693 }
vhost_net() const694 bool CuttlefishConfig::vhost_net() const {
695   return (*dictionary_)[kVhostNet].asBool();
696 }
697 
698 static constexpr char kEthernet[] = "ethernet";
set_ethernet(bool ethernet)699 void CuttlefishConfig::set_ethernet(bool ethernet) {
700   (*dictionary_)[kEthernet] = ethernet;
701 }
ethernet() const702 bool CuttlefishConfig::ethernet() const {
703   return (*dictionary_)[kEthernet].asBool();
704 }
705 
706 static constexpr char kRecordScreen[] = "record_screen";
set_record_screen(bool record_screen)707 void CuttlefishConfig::set_record_screen(bool record_screen) {
708   (*dictionary_)[kRecordScreen] = record_screen;
709 }
record_screen() const710 bool CuttlefishConfig::record_screen() const {
711   return (*dictionary_)[kRecordScreen].asBool();
712 }
713 
714 static constexpr char kSmt[] = "smt";
set_smt(bool smt)715 void CuttlefishConfig::set_smt(bool smt) {
716   (*dictionary_)[kSmt] = smt;
717 }
smt() const718 bool CuttlefishConfig::smt() const {
719   return (*dictionary_)[kSmt].asBool();
720 }
721 
722 static constexpr char kEnableAudio[] = "enable_audio";
set_enable_audio(bool enable)723 void CuttlefishConfig::set_enable_audio(bool enable) {
724   (*dictionary_)[kEnableAudio] = enable;
725 }
enable_audio() const726 bool CuttlefishConfig::enable_audio() const {
727   return (*dictionary_)[kEnableAudio].asBool();
728 }
729 
730 static constexpr char kProtectedVm[] = "protected_vm";
set_protected_vm(bool protected_vm)731 void CuttlefishConfig::set_protected_vm(bool protected_vm) {
732   (*dictionary_)[kProtectedVm] = protected_vm;
733 }
protected_vm() const734 bool CuttlefishConfig::protected_vm() const {
735   return (*dictionary_)[kProtectedVm].asBool();
736 }
737 
738 static constexpr char kTargetArch[] = "target_arch";
set_target_arch(Arch target_arch)739 void CuttlefishConfig::set_target_arch(Arch target_arch) {
740   (*dictionary_)[kTargetArch] = static_cast<int>(target_arch);
741 }
target_arch() const742 Arch CuttlefishConfig::target_arch() const {
743   return static_cast<Arch>((*dictionary_)[kTargetArch].asInt());
744 }
745 
746 static constexpr char kBootconfigSupported[] = "bootconfig_supported";
bootconfig_supported() const747 bool CuttlefishConfig::bootconfig_supported() const {
748   return (*dictionary_)[kBootconfigSupported].asBool();
749 }
set_bootconfig_supported(bool bootconfig_supported)750 void CuttlefishConfig::set_bootconfig_supported(bool bootconfig_supported) {
751   (*dictionary_)[kBootconfigSupported] = bootconfig_supported;
752 }
753 
754 // Creates the (initially empty) config object and populates it with values from
755 // the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
756 // Returns nullptr if there was an error loading from file
BuildConfigImpl()757 /*static*/ CuttlefishConfig* CuttlefishConfig::BuildConfigImpl() {
758   auto config_file_path = StringFromEnv(kCuttlefishConfigEnvVarName,
759                                         GetGlobalConfigFileLink());
760   auto ret = new CuttlefishConfig();
761   if (ret) {
762     auto loaded = ret->LoadFromFile(config_file_path.c_str());
763     if (!loaded) {
764       delete ret;
765       return nullptr;
766     }
767   }
768   return ret;
769 }
770 
Get()771 /*static*/ const CuttlefishConfig* CuttlefishConfig::Get() {
772   static std::shared_ptr<CuttlefishConfig> config(BuildConfigImpl());
773   return config.get();
774 }
775 
ConfigExists()776 /*static*/ bool CuttlefishConfig::ConfigExists() {
777   auto config_file_path = StringFromEnv(kCuttlefishConfigEnvVarName,
778                                         GetGlobalConfigFileLink());
779   auto real_file_path = AbsolutePath(config_file_path.c_str());
780   return FileExists(real_file_path);
781 }
782 
CuttlefishConfig()783 CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {}
784 // Can't use '= default' on the header because the compiler complains of
785 // Json::Value being an incomplete type
786 CuttlefishConfig::~CuttlefishConfig() = default;
787 
788 CuttlefishConfig::CuttlefishConfig(CuttlefishConfig&&) = default;
789 CuttlefishConfig& CuttlefishConfig::operator=(CuttlefishConfig&&) = default;
790 
LoadFromFile(const char * file)791 bool CuttlefishConfig::LoadFromFile(const char* file) {
792   auto real_file_path = AbsolutePath(file);
793   if (real_file_path.empty()) {
794     LOG(ERROR) << "Could not get real path for file " << file;
795     return false;
796   }
797   Json::CharReaderBuilder builder;
798   std::ifstream ifs(real_file_path);
799   std::string errorMessage;
800   if (!Json::parseFromStream(builder, ifs, dictionary_.get(), &errorMessage)) {
801     LOG(ERROR) << "Could not read config file " << file << ": " << errorMessage;
802     return false;
803   }
804   return true;
805 }
SaveToFile(const std::string & file) const806 bool CuttlefishConfig::SaveToFile(const std::string& file) const {
807   std::ofstream ofs(file);
808   if (!ofs.is_open()) {
809     LOG(ERROR) << "Unable to write to file " << file;
810     return false;
811   }
812   ofs << *dictionary_;
813   return !ofs.fail();
814 }
815 
AssemblyPath(const std::string & file_name) const816 std::string CuttlefishConfig::AssemblyPath(
817     const std::string& file_name) const {
818   return AbsolutePath(assembly_dir() + "/" + file_name);
819 }
820 
ForInstance(int num)821 CuttlefishConfig::MutableInstanceSpecific CuttlefishConfig::ForInstance(int num) {
822   return MutableInstanceSpecific(this, std::to_string(num));
823 }
824 
ForInstance(int num) const825 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForInstance(int num) const {
826   return InstanceSpecific(this, std::to_string(num));
827 }
828 
ForDefaultInstance() const829 CuttlefishConfig::InstanceSpecific CuttlefishConfig::ForDefaultInstance() const {
830   return InstanceSpecific(this, std::to_string(GetInstance()));
831 }
832 
Instances() const833 std::vector<CuttlefishConfig::InstanceSpecific> CuttlefishConfig::Instances() const {
834   const auto& json = (*dictionary_)[kInstances];
835   std::vector<CuttlefishConfig::InstanceSpecific> instances;
836   for (const auto& name : json.getMemberNames()) {
837     instances.push_back(CuttlefishConfig::InstanceSpecific(this, name));
838   }
839   return instances;
840 }
841 
GetInstance()842 int GetInstance() {
843   static int instance_id = InstanceFromEnvironment();
844   return instance_id;
845 }
846 
GetDefaultVsockCid()847 int GetDefaultVsockCid() {
848   // we assume that this function is used to configure CuttlefishConfig once
849   static const int default_vsock_cid = 3 + GetInstance() - 1;
850   return default_vsock_cid;
851 }
852 
GetVsockServerPort(const int base,const int vsock_guest_cid)853 int GetVsockServerPort(const int base,
854                        const int vsock_guest_cid /**< per instance guest cid */) {
855     return base + (vsock_guest_cid - 3);
856 }
857 
GetGlobalConfigFileLink()858 std::string GetGlobalConfigFileLink() {
859   return StringFromEnv("HOME", ".") + "/.cuttlefish_config.json";
860 }
861 
ForCurrentInstance(const char * prefix)862 std::string ForCurrentInstance(const char* prefix) {
863   std::ostringstream stream;
864   stream << prefix << std::setfill('0') << std::setw(2) << GetInstance();
865   return stream.str();
866 }
ForCurrentInstance(int base)867 int ForCurrentInstance(int base) { return base + GetInstance() - 1; }
868 
RandomSerialNumber(const std::string & prefix)869 std::string RandomSerialNumber(const std::string& prefix) {
870   const char hex_characters[] = "0123456789ABCDEF";
871   std::srand(time(0));
872   char str[10];
873   for(int i=0; i<10; i++){
874     str[i] = hex_characters[rand() % strlen(hex_characters)];
875   }
876   return prefix + str;
877 }
878 
DefaultHostArtifactsPath(const std::string & file_name)879 std::string DefaultHostArtifactsPath(const std::string& file_name) {
880   return (StringFromEnv("ANDROID_SOONG_HOST_OUT", StringFromEnv("HOME", ".")) + "/") +
881          file_name;
882 }
883 
HostBinaryPath(const std::string & binary_name)884 std::string HostBinaryPath(const std::string& binary_name) {
885 #ifdef __ANDROID__
886   return binary_name;
887 #else
888   return DefaultHostArtifactsPath("bin/" + binary_name);
889 #endif
890 }
891 
DefaultGuestImagePath(const std::string & file_name)892 std::string DefaultGuestImagePath(const std::string& file_name) {
893   return (StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", "."))) +
894          file_name;
895 }
896 
HostSupportsQemuCli()897 bool HostSupportsQemuCli() {
898   static bool supported =
899       std::system(
900           "/usr/lib/cuttlefish-common/bin/capability_query.py qemu_cli") == 0;
901   return supported;
902 }
903 
904 }  // namespace cuttlefish
905