1 /*
2 * Copyright 2016 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 "code_gen/driver/DriverCodeGenBase.h"
18
19 #include <hidl-util/Formatter.h>
20 #include <hidl-util/FQName.h>
21
22 #include <fstream>
23 #include <iostream>
24 #include <iomanip>
25 #include <limits>
26 #include <sstream>
27 #include <string>
28
29 #include "utils/InterfaceSpecUtil.h"
30
31 #include "VtsCompilerUtils.h"
32 #include "utils/StringUtil.h"
33
34 using namespace std;
35
36 namespace android {
37 namespace vts {
38
GenerateAll(Formatter & header_out,Formatter & source_out,const ComponentSpecificationMessage & message)39 void DriverCodeGenBase::GenerateAll(
40 Formatter& header_out, Formatter& source_out,
41 const ComponentSpecificationMessage& message) {
42 GenerateHeaderFile(header_out, message);
43 GenerateSourceFile(source_out, message);
44 }
45
GenerateHeaderFile(Formatter & out,const ComponentSpecificationMessage & message)46 void DriverCodeGenBase::GenerateHeaderFile(
47 Formatter& out, const ComponentSpecificationMessage& message) {
48 string component_name = GetComponentName(message);
49 if (component_name.empty()) {
50 cerr << __func__ << ":" << __LINE__ << " error component_name is empty"
51 << "\n";
52 exit(-1);
53 }
54 FQName component_fq_name = GetFQName(message);
55 string component_name_token = component_fq_name.tokenName();
56 string fuzzer_extended_class_name;
57 if (message.component_class() == HAL_HIDL) {
58 fuzzer_extended_class_name = "FuzzerExtended_" + component_name_token;
59 } else {
60 fuzzer_extended_class_name = "FuzzerExtended_" + GetComponentName(message);
61 }
62
63 out << "#ifndef __VTS_DRIVER__";
64 if (message.component_class() == HAL_HIDL) {
65 out << component_name_token << "__" << "\n";
66 } else {
67 out << vts_name_ << "__" << "\n";
68 }
69 out << "#define __VTS_DRIVER__";
70 if (message.component_class() == HAL_HIDL) {
71 out << component_name_token << "__" << "\n";
72 } else {
73 out << vts_name_ << "__" << "\n";
74 }
75 out << "\n";
76
77 out << "#undef LOG_TAG\n";
78 out << "#define LOG_TAG \"" << fuzzer_extended_class_name << "\"\n";
79
80 GenerateHeaderIncludeFiles(out, message, fuzzer_extended_class_name);
81
82 GenerateOpenNameSpaces(out, message);
83 GenerateClassHeader(out, message, fuzzer_extended_class_name);
84 out << "\n\n";
85 GenerateHeaderGlobalFunctionDeclarations(out, message);
86 GenerateCloseNameSpaces(out, message);
87 out << "#endif" << "\n";
88 }
89
GenerateSourceFile(Formatter & out,const ComponentSpecificationMessage & message)90 void DriverCodeGenBase::GenerateSourceFile(
91 Formatter& out, const ComponentSpecificationMessage& message) {
92 string component_name = GetComponentName(message);
93 if (component_name.empty()) {
94 cerr << __func__ << ":" << __LINE__ << " error component_name is empty"
95 << "\n";
96 exit(-1);
97 }
98 FQName component_fq_name = GetFQName(message);
99 string component_name_token = component_fq_name.tokenName();
100 string fuzzer_extended_class_name;
101 if (message.component_class() == HAL_HIDL) {
102 fuzzer_extended_class_name = "FuzzerExtended_" + component_name_token;
103 } else {
104 fuzzer_extended_class_name = "FuzzerExtended_" + GetComponentName(message);
105 }
106 GenerateSourceIncludeFiles(out, message, fuzzer_extended_class_name);
107 out << "\n\n";
108 GenerateOpenNameSpaces(out, message);
109 GenerateClassImpl(out, message, fuzzer_extended_class_name);
110 GenerateCppBodyGlobalFunctions(out, message, fuzzer_extended_class_name);
111 GenerateCloseNameSpaces(out, message);
112 }
113
GenerateClassHeader(Formatter & out,const ComponentSpecificationMessage & message,const string & fuzzer_extended_class_name)114 void DriverCodeGenBase::GenerateClassHeader(Formatter& out,
115 const ComponentSpecificationMessage& message,
116 const string& fuzzer_extended_class_name) {
117 out << "class " << fuzzer_extended_class_name << " : public FuzzerBase {"
118 << "\n";
119 out << " public:" << "\n";
120
121 out.indent();
122 GenerateClassConstructionFunction(out, message, fuzzer_extended_class_name);
123 out.unindent();
124
125 out << " protected:" << "\n";
126
127 out.indent();
128 out << "bool Fuzz(FunctionSpecificationMessage* func_msg, void** result, "
129 << "const string& callback_socket_name);\n";
130 out << "bool CallFunction(const FunctionSpecificationMessage& func_msg, "
131 << "const string& callback_socket_name, "
132 << "FunctionSpecificationMessage* result_msg);\n";
133 out << "bool VerifyResults(const FunctionSpecificationMessage& expected_result, "
134 << "const FunctionSpecificationMessage& actual_result);\n";
135 out << "bool GetAttribute(FunctionSpecificationMessage* func_msg, "
136 << "void** result);\n";
137
138 // Produce Fuzz method(s) for sub_struct(s).
139 for (auto const& sub_struct : message.interface().sub_struct()) {
140 GenerateFuzzFunctionForSubStruct(out, sub_struct, "_");
141 }
142 // Generate additional function declarations if any.
143 GenerateAdditionalFuctionDeclarations(out, message,
144 fuzzer_extended_class_name);
145 out.unindent();
146
147 out << " private:" << "\n";
148
149 out.indent();
150 // Generate declarations of private members if any.
151 GeneratePrivateMemberDeclarations(out, message);
152 out.unindent();
153
154 out << "};\n";
155 }
156
GenerateClassImpl(Formatter & out,const ComponentSpecificationMessage & message,const string & fuzzer_extended_class_name)157 void DriverCodeGenBase::GenerateClassImpl(Formatter& out,
158 const ComponentSpecificationMessage& message,
159 const string& fuzzer_extended_class_name) {
160 GenerateCppBodyCallbackFunction(out, message, fuzzer_extended_class_name);
161 GenerateCppBodyFuzzFunction(out, message, fuzzer_extended_class_name);
162 GenerateCppBodyGetAttributeFunction(out, message, fuzzer_extended_class_name);
163 GenerateDriverFunctionImpl(out, message, fuzzer_extended_class_name);
164 GenerateVerificationFunctionImpl(out, message, fuzzer_extended_class_name);
165 }
166
GenerateHeaderIncludeFiles(Formatter & out,const ComponentSpecificationMessage & message,const string &)167 void DriverCodeGenBase::GenerateHeaderIncludeFiles(Formatter& out,
168 const ComponentSpecificationMessage& message, const string&) {
169 for (auto const& header : message.header()) {
170 out << "#include " << header << "\n";
171 }
172 out << "\n";
173 out << "#include <stdio.h>" << "\n";
174 out << "#include <stdarg.h>" << "\n";
175 out << "#include <stdlib.h>" << "\n";
176 out << "#include <string.h>" << "\n";
177 out << "#include <utils/Log.h>" << "\n";
178 out << "\n";
179 out << "#include <fuzz_tester/FuzzerBase.h>" << "\n";
180 out << "#include <fuzz_tester/FuzzerCallbackBase.h>" << "\n";
181 out << "\n";
182 if (message.component_class() == HAL_HIDL &&
183 endsWith(message.component_name(), "Callback")) {
184 out << "#include <VtsDriverCommUtil.h>" << "\n";
185 out << "\n";
186 }
187 }
188
GenerateSourceIncludeFiles(Formatter & out,const ComponentSpecificationMessage & message,const string &)189 void DriverCodeGenBase::GenerateSourceIncludeFiles(Formatter& out,
190 const ComponentSpecificationMessage& message, const string&) {
191 out << "#include \"" << input_vts_file_path_ << ".h\"" << "\n";
192
193 for (auto const& header : message.header()) {
194 out << "#include " << header << "\n";
195 }
196 if (message.component_class() != HAL_HIDL) {
197 out << "#include \"vts_datatype.h\"" << "\n";
198 }
199 out << "#include \"vts_measurement.h\"" << "\n";
200 out << "#include <iostream>" << "\n";
201 }
202
GenerateHeaderGlobalFunctionDeclarations(Formatter & out,const ComponentSpecificationMessage & message)203 void DriverCodeGenBase::GenerateHeaderGlobalFunctionDeclarations(Formatter& out,
204 const ComponentSpecificationMessage& message) {
205 string function_name_prefix = GetFunctionNamePrefix(message);
206
207 out << "extern \"C\" {" << "\n";
208 out << "extern " << "android::vts::FuzzerBase* " << function_name_prefix
209 << "();\n";
210 out << "}" << "\n";
211 }
212
GenerateCppBodyGlobalFunctions(Formatter & out,const ComponentSpecificationMessage & message,const string & fuzzer_extended_class_name)213 void DriverCodeGenBase::GenerateCppBodyGlobalFunctions(Formatter& out,
214 const ComponentSpecificationMessage& message,
215 const string& fuzzer_extended_class_name) {
216 string function_name_prefix = GetFunctionNamePrefix(message);
217
218 out << "extern \"C\" {" << "\n";
219 out << "android::vts::FuzzerBase* " << function_name_prefix << "() {\n";
220 out.indent();
221 out << "return (android::vts::FuzzerBase*) " << "new android::vts::";
222 out << fuzzer_extended_class_name << "();\n";
223 out.unindent();
224 out << "}\n\n";
225 out << "}\n";
226 }
227
GenerateFuzzFunctionForSubStruct(Formatter & out,const StructSpecificationMessage & message,const string & parent_path)228 void DriverCodeGenBase::GenerateFuzzFunctionForSubStruct(
229 Formatter& out, const StructSpecificationMessage& message,
230 const string& parent_path) {
231 out.indent();
232 out << "bool Fuzz_" << parent_path << message.name()
233 << "(FunctionSpecificationMessage* func_msg," << "\n";
234 out << " void** result, const string& callback_socket_name);"
235 << "\n";
236
237 out << "bool GetAttribute_" << parent_path << message.name()
238 << "(FunctionSpecificationMessage* func_msg," << "\n";
239 out << " void** result);"
240 << "\n";
241
242 for (auto const& sub_struct : message.sub_struct()) {
243 GenerateFuzzFunctionForSubStruct(out, sub_struct,
244 parent_path + message.name() + "_");
245 }
246 out.unindent();
247 }
248
GenerateDriverFunctionImpl(Formatter & out,const ComponentSpecificationMessage &,const string & fuzzer_extended_class_name)249 void DriverCodeGenBase::GenerateDriverFunctionImpl(Formatter& out,
250 const ComponentSpecificationMessage& /*message*/,
251 const string& fuzzer_extended_class_name) {
252 out << "bool " << fuzzer_extended_class_name
253 << "::CallFunction(const FunctionSpecificationMessage&, const string&, "
254 << "FunctionSpecificationMessage* ) {\n";
255 out.indent();
256 out << "/* No implementation yet. */\n";
257 out << "return true;\n";
258 out.unindent();
259 out << "}\n";
260 }
261
GenerateVerificationFunctionImpl(Formatter & out,const ComponentSpecificationMessage &,const string & fuzzer_extended_class_name)262 void DriverCodeGenBase::GenerateVerificationFunctionImpl(Formatter& out,
263 const ComponentSpecificationMessage& /*message*/,
264 const string& fuzzer_extended_class_name) {
265 out << "bool " << fuzzer_extended_class_name
266 << "::VerifyResults(const FunctionSpecificationMessage&, "
267 << "const FunctionSpecificationMessage&) {\n";
268 out.indent();
269 out << "/* No implementation yet. */\n";
270 out << "return true;\n";
271 out.unindent();
272 out << "}\n";
273 }
274
GenerateNamespaceName(Formatter & out,const ComponentSpecificationMessage & message)275 void DriverCodeGenBase::GenerateNamespaceName(
276 Formatter& out, const ComponentSpecificationMessage& message) {
277 if (message.component_class() == HAL_HIDL && message.has_package()) {
278 string name = message.package();
279 ReplaceSubString(name, ".", "::");
280 out << name << "::"
281 << GetVersionString(message.component_type_version(), true);
282 } else {
283 cerr << __func__ << ":" << __LINE__ << " no namespace" << "\n";
284 exit(-1);
285 }
286 }
287
GenerateOpenNameSpaces(Formatter & out,const ComponentSpecificationMessage & message)288 void DriverCodeGenBase::GenerateOpenNameSpaces(Formatter& out,
289 const ComponentSpecificationMessage& message) {
290 if (message.component_class() == HAL_HIDL && message.has_package()) {
291 out << "using namespace ";
292 GenerateNamespaceName(out, message);
293 out << ";" << "\n";
294 }
295
296 out << "namespace android {" << "\n";
297 out << "namespace vts {" << "\n";
298 }
299
GenerateCloseNameSpaces(Formatter & out,const ComponentSpecificationMessage &)300 void DriverCodeGenBase::GenerateCloseNameSpaces(Formatter& out,
301 const ComponentSpecificationMessage& /*message*/) {
302 out << "} // namespace vts" << "\n";
303 out << "} // namespace android" << "\n";
304 }
305
GenerateCodeToStartMeasurement(Formatter & out)306 void DriverCodeGenBase::GenerateCodeToStartMeasurement(Formatter& out) {
307 out << "VtsMeasurement vts_measurement;" << "\n";
308 out << "vts_measurement.Start();" << "\n";
309 }
310
GenerateCodeToStopMeasurement(Formatter & out)311 void DriverCodeGenBase::GenerateCodeToStopMeasurement(Formatter& out) {
312 out << "vector<float>* measured = vts_measurement.Stop();" << "\n";
313 out << "cout << \"time \" << (*measured)[0] << endl;" << "\n";
314 }
315
316 } // namespace vts
317 } // namespace android
318