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