• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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