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