• 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 "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