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 "ProfilerCodeGenBase.h"
18 #include "utils/InterfaceSpecUtil.h"
19 #include "utils/StringUtil.h"
20 #include "VtsCompilerUtils.h"
21
22 namespace android {
23 namespace vts {
24
ProfilerCodeGenBase(const std::string & input_vts_file_path)25 ProfilerCodeGenBase::ProfilerCodeGenBase(const std::string& input_vts_file_path)
26 : input_vts_file_path_(input_vts_file_path) {
27 }
28
~ProfilerCodeGenBase()29 ProfilerCodeGenBase::~ProfilerCodeGenBase() {
30 }
31
GenerateAll(Formatter & header_out,Formatter & source_out,const ComponentSpecificationMessage & message)32 void ProfilerCodeGenBase::GenerateAll(
33 Formatter& header_out, Formatter& source_out,
34 const ComponentSpecificationMessage& message) {
35 GenerateHeaderFile(header_out, message);
36 GenerateSourceFile(source_out, message);
37 }
38
GenerateHeaderFile(Formatter & out,const ComponentSpecificationMessage & message)39 void ProfilerCodeGenBase::GenerateHeaderFile(
40 Formatter& out, const ComponentSpecificationMessage& message) {
41 FQName component_fq_name = GetFQName(message);
42 out << "#ifndef __VTS_PROFILER_" << component_fq_name.tokenName()
43 << "__\n";
44 out << "#define __VTS_PROFILER_" << component_fq_name.tokenName()
45 << "__\n";
46 out << "\n\n";
47 GenerateHeaderIncludeFiles(out, message);
48 GenerateUsingDeclaration(out, message);
49 GenerateOpenNameSpaces(out, message);
50
51 if (message.has_interface()) {
52 InterfaceSpecificationMessage interface = message.interface();
53 // First generate the declaration of profiler functions for all user
54 // defined types within the interface.
55 for (const auto attribute : interface.attribute()) {
56 GenerateProfilerMethodDeclForAttribute(out, attribute);
57 }
58
59 out << "extern \"C\" {\n";
60 out.indent();
61
62 // Generate the declaration of main profiler function.
63 FQName component_fq_name = GetFQName(message);
64 out << "\nvoid HIDL_INSTRUMENTATION_FUNCTION_" << component_fq_name.tokenName()
65 << "(\n";
66 out.indent();
67 out.indent();
68 out << "details::HidlInstrumentor::InstrumentationEvent event,\n";
69 out << "const char* package,\n";
70 out << "const char* version,\n";
71 out << "const char* interface,\n";
72 out << "const char* method,\n";
73 out << "std::vector<void *> *args);\n";
74 out.unindent();
75 out.unindent();
76
77 out.unindent();
78 out << "}\n\n";
79 } else {
80 // For types.vts, just generate the declaration of profiler functions
81 // for all user defined types.
82 for (const auto attribute : message.attribute()) {
83 GenerateProfilerMethodDeclForAttribute(out, attribute);
84 }
85 }
86
87 GenerateCloseNameSpaces(out, message);
88 out << "#endif\n";
89 }
90
GenerateSourceFile(Formatter & out,const ComponentSpecificationMessage & message)91 void ProfilerCodeGenBase::GenerateSourceFile(
92 Formatter& out, const ComponentSpecificationMessage& message) {
93 GenerateSourceIncludeFiles(out, message);
94 GenerateUsingDeclaration(out, message);
95 GenerateMacros(out, message);
96 GenerateOpenNameSpaces(out, message);
97
98 if (message.has_interface()) {
99 InterfaceSpecificationMessage interface = message.interface();
100 // First generate profiler functions for all user defined types within
101 // the interface.
102 for (const auto attribute : interface.attribute()) {
103 GenerateProfilerMethodImplForAttribute(out, attribute);
104 }
105 // Generate the main profiler function.
106 FQName component_fq_name = GetFQName(message);
107 out << "\nvoid HIDL_INSTRUMENTATION_FUNCTION_" << component_fq_name.tokenName()
108 << "(\n";
109 out.indent();
110 out.indent();
111 out << "details::HidlInstrumentor::InstrumentationEvent event,\n";
112 out << "const char* package,\n";
113 out << "const char* version,\n";
114 out << "const char* interface,\n";
115 out << "const char* method,\n";
116 out << "std::vector<void *> *args) {\n";
117 out.unindent();
118
119 // Generate code for sanity check.
120 GenerateProfierSanityCheck(out, message);
121
122 // Generate code to define local variables.
123 GenerateLocalVariableDefinition(out, message);
124
125 // Generate the profiler code for each method.
126 for (const FunctionSpecificationMessage api : interface.api()) {
127 out << "if (strcmp(method, \"" << api.name() << "\") == 0) {\n";
128 out.indent();
129 GenerateProfilerForMethod(out, api);
130 out.unindent();
131 out << "}\n";
132 }
133
134 out.unindent();
135 out << "}\n\n";
136 } else {
137 // For types.vts, just generate profiler functions for the user defined
138 // types.
139 for (const auto attribute : message.attribute()) {
140 GenerateProfilerMethodImplForAttribute(out, attribute);
141 }
142 }
143
144 GenerateCloseNameSpaces(out, message);
145 }
146
GenerateProfilerForTypedVariable(Formatter & out,const VariableSpecificationMessage & val,const std::string & arg_name,const std::string & arg_value)147 void ProfilerCodeGenBase::GenerateProfilerForTypedVariable(Formatter& out,
148 const VariableSpecificationMessage& val, const std::string& arg_name,
149 const std::string& arg_value) {
150 switch (val.type()) {
151 case TYPE_SCALAR:
152 {
153 GenerateProfilerForScalarVariable(out, val, arg_name, arg_value);
154 break;
155 }
156 case TYPE_STRING:
157 {
158 GenerateProfilerForStringVariable(out, val, arg_name, arg_value);
159 break;
160 }
161 case TYPE_ENUM:
162 {
163 GenerateProfilerForEnumVariable(out, val, arg_name, arg_value);
164 break;
165 }
166 case TYPE_VECTOR:
167 {
168 GenerateProfilerForVectorVariable(out, val, arg_name, arg_value);
169 break;
170 }
171 case TYPE_ARRAY:
172 {
173 GenerateProfilerForArrayVariable(out, val, arg_name, arg_value);
174 break;
175 }
176 case TYPE_STRUCT:
177 {
178 GenerateProfilerForStructVariable(out, val, arg_name, arg_value);
179 break;
180 }
181 case TYPE_UNION: {
182 GenerateProfilerForUnionVariable(out, val, arg_name, arg_value);
183 break;
184 }
185 case TYPE_HIDL_CALLBACK:
186 {
187 GenerateProfilerForHidlCallbackVariable(out, val, arg_name, arg_value);
188 break;
189 }
190 case TYPE_HIDL_INTERFACE:
191 {
192 GenerateProfilerForHidlInterfaceVariable(out, val, arg_name, arg_value);
193 break;
194 }
195 case TYPE_MASK:
196 {
197 GenerateProfilerForMaskVariable(out, val, arg_name, arg_value);
198 break;
199 }
200 case TYPE_HIDL_MEMORY:
201 {
202 GenerateProfilerForHidlMemoryVariable(out, val, arg_name, arg_value);
203 break;
204 }
205 case TYPE_POINTER:
206 {
207 GenerateProfilerForPointerVariable(out, val, arg_name, arg_value);
208 break;
209 }
210 case TYPE_FMQ_SYNC:
211 {
212 GenerateProfilerForFMQSyncVariable(out, val, arg_name, arg_value);
213 break;
214 }
215 case TYPE_FMQ_UNSYNC:
216 {
217 GenerateProfilerForFMQUnsyncVariable(out, val, arg_name, arg_value);
218 break;
219 }
220 default:
221 {
222 cout << "not supported.\n";
223 }
224 }
225 }
226
GenerateProfilerMethodDeclForAttribute(Formatter & out,const VariableSpecificationMessage & attribute)227 void ProfilerCodeGenBase::GenerateProfilerMethodDeclForAttribute(Formatter& out,
228 const VariableSpecificationMessage& attribute) {
229 if (attribute.type() == TYPE_STRUCT || attribute.type() == TYPE_UNION) {
230 // Recursively generate profiler method declaration for all sub_types.
231 for (const auto sub_struct : attribute.sub_struct()) {
232 GenerateProfilerMethodDeclForAttribute(out, sub_struct);
233 }
234 for (const auto sub_union : attribute.sub_union()) {
235 GenerateProfilerMethodDeclForAttribute(out, sub_union);
236 }
237 }
238 std::string attribute_name = attribute.name();
239 ReplaceSubString(attribute_name, "::", "__");
240 out << "void profile__" << attribute_name
241 << "(VariableSpecificationMessage* arg_name,\n" << attribute.name()
242 << " arg_val_name);\n";
243 }
244
GenerateProfilerMethodImplForAttribute(Formatter & out,const VariableSpecificationMessage & attribute)245 void ProfilerCodeGenBase::GenerateProfilerMethodImplForAttribute(
246 Formatter& out, const VariableSpecificationMessage& attribute) {
247 if (attribute.type() == TYPE_STRUCT || attribute.type() == TYPE_UNION) {
248 // Recursively generate profiler method implementation for all sub_types.
249 for (const auto sub_struct : attribute.sub_struct()) {
250 GenerateProfilerMethodImplForAttribute(out, sub_struct);
251 }
252 for (const auto sub_union : attribute.sub_union()) {
253 GenerateProfilerMethodImplForAttribute(out, sub_union);
254 }
255 }
256 std::string attribute_name = attribute.name();
257 ReplaceSubString(attribute_name, "::", "__");
258 out << "void profile__" << attribute_name
259 << "(VariableSpecificationMessage* arg_name,\n" << attribute.name()
260 << " arg_val_name) {\n";
261 out.indent();
262 GenerateProfilerForTypedVariable(out, attribute, "arg_name", "arg_val_name");
263 out.unindent();
264 out << "}\n\n";
265 }
266
GenerateOpenNameSpaces(Formatter & out,const ComponentSpecificationMessage &)267 void ProfilerCodeGenBase::GenerateOpenNameSpaces(Formatter& out,
268 const ComponentSpecificationMessage& /*message*/) {
269 out << "namespace android {\n";
270 out << "namespace vts {\n";
271 }
272
GenerateCloseNameSpaces(Formatter & out,const ComponentSpecificationMessage &)273 void ProfilerCodeGenBase::GenerateCloseNameSpaces(Formatter& out,
274 const ComponentSpecificationMessage& /*message*/) {
275 out << "} // namespace vts\n";
276 out << "} // namespace android\n";
277 }
278
GetPackage(const ComponentSpecificationMessage & message)279 std::string ProfilerCodeGenBase::GetPackage(
280 const ComponentSpecificationMessage& message) {
281 return message.package();
282 }
GetPackageVersion(const ComponentSpecificationMessage & message)283 std::string ProfilerCodeGenBase::GetPackageVersion(
284 const ComponentSpecificationMessage& message) {
285 return GetVersionString(message.component_type_version());
286 }
GetComponentName(const ComponentSpecificationMessage & message)287 std::string ProfilerCodeGenBase::GetComponentName(
288 const ComponentSpecificationMessage& message) {
289 return message.component_name();
290 }
291
292 } // namespace vts
293 } // namespace android
294