1 /*
2 * Copyright (C) 2023 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 #include <android-base/file.h>
17 #include <gflags/gflags.h>
18
19 #include <stdio.h>
20 #include <fstream>
21 #include <string>
22 #include <unordered_set>
23
24 #include "common/libs/utils/files.h"
25 #include "common/libs/utils/flags_validator.h"
26 #include "common/libs/utils/json.h"
27 #include "host/commands/cvd/parser/cf_configs_common.h"
28
29 namespace cuttlefish {
30
31 // json main parameters definitions
32 static std::map<std::string, Json::ValueType> kConfigsKeyMap = {
33 {"credential", Json::ValueType::stringValue},
34 {"netsim_bt", Json::ValueType::booleanValue},
35 {"instances", Json::ValueType::arrayValue}};
36
37 // instance object parameters definitions
38 static std::map<std::string, Json::ValueType> kInstanceKeyMap = {
39 {"@import", Json::ValueType::stringValue},
40 {"vm", Json::ValueType::objectValue},
41 {"boot", Json::ValueType::objectValue},
42 {"security", Json::ValueType::objectValue},
43 {"disk", Json::ValueType::objectValue},
44 {"graphics", Json::ValueType::objectValue},
45 {"camera", Json::ValueType::objectValue},
46 {"connectivity", Json::ValueType::objectValue},
47 {"audio", Json::ValueType::objectValue},
48 {"streaming", Json::ValueType::objectValue},
49 {"adb", Json::ValueType::objectValue},
50 {"vehicle", Json::ValueType::objectValue},
51 {"location", Json::ValueType::objectValue}};
52
53 // supported import values for @import key
54 static std::unordered_set<std::string> kSupportedImportValues = {
55 "phone", "tablet", "tv", "wearable", "auto", "slim", "go", "foldable"};
56
57 // supported import values for vm category and crosvm subcategory
58 static std::map<std::string, Json::ValueType> kVmKeyMap = {
59 {"cpus", Json::ValueType::uintValue},
60 {"memory_mb", Json::ValueType::uintValue},
61 {"use_sdcard", Json::ValueType::booleanValue},
62 {"setupwizard_mode", Json::ValueType::stringValue},
63 {"uuid", Json::ValueType::stringValue},
64 {"crosvm", Json::ValueType::objectValue},
65 {"qemu", Json::ValueType::objectValue},
66 {"gem5", Json::ValueType::objectValue},
67 {"custom_actions", Json::ValueType::arrayValue},
68 };
69 static std::map<std::string, Json::ValueType> kCrosvmKeyMap = {
70 {"enable_sandbox", Json::ValueType::booleanValue},
71 };
72
73 // supported import values for boot category and kernel subcategory
74 static std::map<std::string, Json::ValueType> kBootKeyMap = {
75 {"extra_bootconfig_args", Json::ValueType::stringValue},
76 {"kernel", Json::ValueType::objectValue},
77 {"enable_bootanimation", Json::ValueType::booleanValue},
78 };
79 static std::map<std::string, Json::ValueType> kernelkeyMap = {
80 {"extra_kernel_cmdline", Json::ValueType::stringValue},
81 };
82
83 // supported import values for graphics category and displays subcategory
84 static std::map<std::string, Json::ValueType> kGraphicsKeyMap = {
85 {"displays", Json::ValueType::arrayValue},
86 };
87 static std::map<std::string, Json::ValueType> kDisplayKeyMap = {
88 {"width", Json::ValueType::uintValue},
89 {"height", Json::ValueType::uintValue},
90 {"dpi", Json::ValueType::uintValue},
91 {"refresh_rate_hertz", Json::ValueType::uintValue},
92 };
93
94 // supported import values for security category
95 static std::map<std::string, Json::ValueType> kSecurityKeyMap = {
96 {"serial_number", Json::ValueType::stringValue},
97 {"guest_enforce_security", Json::ValueType::booleanValue},
98 };
99
100 // supported import values for disk category
101 static std::map<std::string, Json::ValueType> kDiskKeyMap = {
102 {"default_build", Json::ValueType::stringValue},
103 {"system_build", Json::ValueType::stringValue},
104 {"kernel_build", Json::ValueType::stringValue},
105 };
106
107 // Validate the security json parameters
ValidateSecurityConfigs(const Json::Value & root)108 Result<void> ValidateSecurityConfigs(const Json::Value& root) {
109 CF_EXPECT(ValidateTypo(root, kSecurityKeyMap),
110 "ValidateSecurityConfigs ValidateTypo fail");
111 return {};
112 }
ValidateDiskConfigs(const Json::Value & root)113 Result<void> ValidateDiskConfigs(const Json::Value& root) {
114 CF_EXPECT(ValidateTypo(root, kDiskKeyMap),
115 "ValidateDiskConfigs ValidateTypo fail");
116 return {};
117 }
118
119 // Validate the displays json parameters
ValidateDisplaysConfigs(const Json::Value & root)120 Result<void> ValidateDisplaysConfigs(const Json::Value& root) {
121 CF_EXPECT(ValidateTypo(root, kDisplayKeyMap),
122 "ValidateDisplaysConfigs ValidateTypo fail");
123 return {};
124 }
125
126 // Validate the graphics json parameters
ValidateGraphicsConfigs(const Json::Value & root)127 Result<void> ValidateGraphicsConfigs(const Json::Value& root) {
128 CF_EXPECT(ValidateTypo(root, kGraphicsKeyMap),
129 "ValidateGraphicsConfigs ValidateTypo fail");
130
131 if (root.isMember("displays") && root["displays"].size() != 0) {
132 int num_displays = root["displays"].size();
133 for (int i = 0; i < num_displays; i++) {
134 CF_EXPECT(ValidateDisplaysConfigs(root["displays"][i]),
135 "ValidateDisplaysConfigs fail");
136 }
137 }
138
139 return {};
140 }
141
142 // Validate the vm json parameters
ValidateVmConfigs(const Json::Value & root)143 Result<void> ValidateVmConfigs(const Json::Value& root) {
144 CF_EXPECT(ValidateTypo(root, kVmKeyMap),
145 "ValidateVmConfigs ValidateTypo fail");
146 if (root.isMember("crosvm")) {
147 CF_EXPECT(ValidateTypo(root["crosvm"], kCrosvmKeyMap),
148 "ValidateVmConfigs ValidateTypo crosvm fail");
149 }
150 return {};
151 }
152
153 // Validate the kernel json parameters
ValidateKernelConfigs(const Json::Value & root)154 Result<void> ValidateKernelConfigs(const Json::Value& root) {
155 CF_EXPECT(ValidateTypo(root, kernelkeyMap),
156 "ValidateKernelConfigs ValidateTypo fail");
157 return {};
158 }
159
160 // Validate the boot json parameters
ValidateBootConfigs(const Json::Value & root)161 Result<void> ValidateBootConfigs(const Json::Value& root) {
162 CF_EXPECT(ValidateTypo(root, kBootKeyMap),
163 "ValidateBootConfigs ValidateTypo fail");
164
165 if (root.isMember("kernel")) {
166 CF_EXPECT(ValidateKernelConfigs(root["kernel"]),
167 "ValidateKernelConfigs fail");
168 }
169
170 return {};
171 }
172
173 // Validate the instances json parameters
ValidateInstancesConfigs(const Json::Value & root)174 Result<void> ValidateInstancesConfigs(const Json::Value& root) {
175 int num_instances = root.size();
176 for (unsigned int i = 0; i < num_instances; i++) {
177 CF_EXPECT(ValidateTypo(root[i], kInstanceKeyMap), "vm ValidateTypo fail");
178
179 if (root[i].isMember("vm")) {
180 CF_EXPECT(ValidateVmConfigs(root[i]["vm"]), "ValidateVmConfigs fail");
181 }
182
183 // Validate @import flag values are supported or not
184 if (root[i].isMember("@import")) {
185 CF_EXPECT(kSupportedImportValues.count(root[i]["@import"].asString()) > 0,
186 "@Import flag values are not supported");
187 }
188
189 if (root[i].isMember("boot")) {
190 CF_EXPECT(ValidateBootConfigs(root[i]["boot"]),
191 "ValidateBootConfigs fail");
192 }
193 if (root[i].isMember("security")) {
194 CF_EXPECT(ValidateSecurityConfigs(root[i]["security"]),
195 "ValidateSecurityConfigs fail");
196 }
197 if (root[i].isMember("disk")) {
198 CF_EXPECT(ValidateDiskConfigs(root[i]["disk"]),
199 "ValidateDiskConfigs fail");
200 }
201 if (root[i].isMember("graphics")) {
202 CF_EXPECT(ValidateGraphicsConfigs(root[i]["graphics"]),
203 "ValidateGraphicsConfigs fail");
204 }
205 }
206 CF_EXPECT(ValidateStringConfig(root, "vm", "setupwizard_mode",
207 ValidateStupWizardMode),
208 "Invalid value for setupwizard_mode flag");
209
210 return {};
211 }
212
213 // Validate cuttlefish config json parameters
ValidateCfConfigs(const Json::Value & root)214 Result<void> ValidateCfConfigs(const Json::Value& root) {
215 CF_EXPECT(ValidateTypo(root, kConfigsKeyMap),
216 "Typo in config main parameters");
217 CF_EXPECT(root.isMember("instances"), "instances object is missing");
218 CF_EXPECT(ValidateInstancesConfigs(root["instances"]),
219 "ValidateInstancesConfigs failed");
220
221 return {};
222 }
223
224 } // namespace cuttlefish
225