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 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 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 55 string component_name_token; 56 if (message.component_class() == HAL_HIDL) { 57 FQName component_fq_name = GetFQName(message); 58 component_name_token = component_fq_name.tokenName(); 59 } else { 60 string version = GetVersion(message, true); 61 component_name_token = 62 ComponentClassToString(message.component_class()) + "_" + 63 ComponentTypeToString(message.component_type()) + "_" + version; 64 } 65 string fuzzer_extended_class_name; 66 if (message.component_class() == HAL_HIDL) { 67 fuzzer_extended_class_name = "FuzzerExtended_" + component_name_token; 68 } else { 69 fuzzer_extended_class_name = "FuzzerExtended_" + GetComponentName(message); 70 } 71 72 out << "#ifndef __VTS_DRIVER__" << component_name_token << "__\n"; 73 out << "#define __VTS_DRIVER__" << component_name_token << "__\n"; 74 out << "\n"; 75 76 out << "#undef LOG_TAG\n"; 77 out << "#define LOG_TAG \"" << fuzzer_extended_class_name << "\"\n"; 78 79 GenerateHeaderIncludeFiles(out, message, fuzzer_extended_class_name); 80 81 GenerateOpenNameSpaces(out, message); 82 GenerateClassHeader(out, message, fuzzer_extended_class_name); 83 out << "\n\n"; 84 GenerateHeaderGlobalFunctionDeclarations(out, message); 85 GenerateCloseNameSpaces(out, message); 86 out << "#endif" << "\n"; 87 } 88 89 void DriverCodeGenBase::GenerateSourceFile( 90 Formatter& out, const ComponentSpecificationMessage& message) { 91 string component_name = GetComponentName(message); 92 if (component_name.empty()) { 93 cerr << __func__ << ":" << __LINE__ << " error component_name is empty" 94 << "\n"; 95 exit(-1); 96 } 97 FQName component_fq_name = GetFQName(message); 98 string component_name_token = component_fq_name.tokenName(); 99 string fuzzer_extended_class_name; 100 if (message.component_class() == HAL_HIDL) { 101 fuzzer_extended_class_name = "FuzzerExtended_" + component_name_token; 102 } else { 103 fuzzer_extended_class_name = "FuzzerExtended_" + GetComponentName(message); 104 } 105 GenerateSourceIncludeFiles(out, message, fuzzer_extended_class_name); 106 out << "\n\n"; 107 GenerateOpenNameSpaces(out, message); 108 GenerateClassImpl(out, message, fuzzer_extended_class_name); 109 GenerateCppBodyGlobalFunctions(out, message, fuzzer_extended_class_name); 110 GenerateCloseNameSpaces(out, message); 111 } 112 113 void DriverCodeGenBase::GenerateClassHeader(Formatter& out, 114 const ComponentSpecificationMessage& message, 115 const string& fuzzer_extended_class_name) { 116 GenerateHeaderInterfaceImpl(out, message); 117 out << "class " << fuzzer_extended_class_name << " : public DriverBase {" 118 << "\n"; 119 out << " public:" << "\n"; 120 121 out.indent(); 122 GenerateClassConstructionFunction(out, message, fuzzer_extended_class_name); 123 GeneratePublicFunctionDeclarations(out, message); 124 out.unindent(); 125 126 out << " protected:" << "\n"; 127 128 out.indent(); 129 out << "bool Fuzz(FunctionSpecificationMessage* func_msg, void** result, " 130 << "const string& callback_socket_name);\n"; 131 out << "bool CallFunction(const FunctionSpecificationMessage& func_msg, " 132 << "const string& callback_socket_name, " 133 << "FunctionSpecificationMessage* result_msg);\n"; 134 out << "bool VerifyResults(const FunctionSpecificationMessage& expected_result, " 135 << "const FunctionSpecificationMessage& actual_result);\n"; 136 out << "bool GetAttribute(FunctionSpecificationMessage* func_msg, " 137 << "void** result);\n"; 138 139 // Produce Fuzz method(s) for sub_struct(s). 140 for (auto const& sub_struct : message.interface().sub_struct()) { 141 GenerateFuzzFunctionForSubStruct(out, sub_struct, "_"); 142 } 143 // Generate additional function declarations if any. 144 GenerateAdditionalFuctionDeclarations(out, message, 145 fuzzer_extended_class_name); 146 out.unindent(); 147 148 out << " private:" << "\n"; 149 150 out.indent(); 151 // Generate declarations of private members if any. 152 GeneratePrivateMemberDeclarations(out, message); 153 out.unindent(); 154 155 out << "};\n"; 156 } 157 158 void DriverCodeGenBase::GenerateClassImpl(Formatter& out, 159 const ComponentSpecificationMessage& message, 160 const string& fuzzer_extended_class_name) { 161 GenerateCppBodyInterfaceImpl(out, message, fuzzer_extended_class_name); 162 GenerateCppBodyFuzzFunction(out, message, fuzzer_extended_class_name); 163 GenerateCppBodyGetAttributeFunction(out, message, fuzzer_extended_class_name); 164 GenerateDriverFunctionImpl(out, message, fuzzer_extended_class_name); 165 GenerateVerificationFunctionImpl(out, message, fuzzer_extended_class_name); 166 } 167 168 void DriverCodeGenBase::GenerateHeaderIncludeFiles(Formatter& out, 169 const ComponentSpecificationMessage& message, const string&) { 170 for (auto const& header : message.header()) { 171 out << "#include " << header << "\n"; 172 } 173 out << "\n"; 174 out << "#include <stdio.h>" << "\n"; 175 out << "#include <stdarg.h>" << "\n"; 176 out << "#include <stdlib.h>" << "\n"; 177 out << "#include <string.h>" << "\n"; 178 out << "#include <utils/Log.h>" << "\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 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 <iostream>" << "\n"; 206 } 207 208 void DriverCodeGenBase::GenerateHeaderGlobalFunctionDeclarations( 209 Formatter& out, const ComponentSpecificationMessage& message, 210 const bool print_extern_block) { 211 string function_name_prefix = GetFunctionNamePrefix(message); 212 213 if (print_extern_block) { 214 out << "extern \"C\" {" << "\n"; 215 } 216 out << "extern " 217 << "android::vts::DriverBase* " << function_name_prefix << "();\n"; 218 if (print_extern_block) { 219 out << "}" << "\n"; 220 } 221 } 222 223 void DriverCodeGenBase::GenerateCppBodyGlobalFunctions( 224 Formatter& out, const ComponentSpecificationMessage& message, 225 const string& fuzzer_extended_class_name, const bool print_extern_block) { 226 string function_name_prefix = GetFunctionNamePrefix(message); 227 228 if (print_extern_block) { 229 out << "extern \"C\" {" << "\n"; 230 } 231 out << "android::vts::DriverBase* " << function_name_prefix << "() {\n"; 232 out.indent(); 233 out << "return (android::vts::DriverBase*) " 234 << "new android::vts::"; 235 out << fuzzer_extended_class_name << "();\n"; 236 out.unindent(); 237 out << "}\n\n"; 238 if (print_extern_block) { 239 out << "}\n"; 240 } 241 } 242 243 void DriverCodeGenBase::GenerateFuzzFunctionForSubStruct( 244 Formatter& out, const StructSpecificationMessage& message, 245 const string& parent_path) { 246 out.indent(); 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 out.unindent(); 263 } 264 265 void DriverCodeGenBase::GenerateDriverFunctionImpl(Formatter& out, 266 const ComponentSpecificationMessage& /*message*/, 267 const string& fuzzer_extended_class_name) { 268 out << "bool " << fuzzer_extended_class_name 269 << "::CallFunction(const FunctionSpecificationMessage&, const string&, " 270 << "FunctionSpecificationMessage* ) {\n"; 271 out.indent(); 272 out << "/* No implementation yet. */\n"; 273 out << "return true;\n"; 274 out.unindent(); 275 out << "}\n"; 276 } 277 278 void DriverCodeGenBase::GenerateVerificationFunctionImpl(Formatter& out, 279 const ComponentSpecificationMessage& /*message*/, 280 const string& fuzzer_extended_class_name) { 281 out << "bool " << fuzzer_extended_class_name 282 << "::VerifyResults(const FunctionSpecificationMessage&, " 283 << "const FunctionSpecificationMessage&) {\n"; 284 out.indent(); 285 out << "/* No implementation yet. */\n"; 286 out << "return true;\n"; 287 out.unindent(); 288 out << "}\n"; 289 } 290 291 void DriverCodeGenBase::GenerateNamespaceName( 292 Formatter& out, const ComponentSpecificationMessage& message) { 293 if (message.component_class() == HAL_HIDL && message.has_package()) { 294 out << GetPackageNamespaceToken(message) 295 << "::" << GetVersion(message, true); 296 } else { 297 cerr << __func__ << ":" << __LINE__ << " no namespace" << "\n"; 298 exit(-1); 299 } 300 } 301 302 void DriverCodeGenBase::GenerateOpenNameSpaces(Formatter& out, 303 const ComponentSpecificationMessage& message) { 304 if (message.component_class() == HAL_HIDL && message.has_package()) { 305 out << "using namespace "; 306 GenerateNamespaceName(out, message); 307 out << ";" << "\n"; 308 } 309 310 out << "namespace android {" << "\n"; 311 out << "namespace vts {" << "\n"; 312 } 313 314 void DriverCodeGenBase::GenerateCloseNameSpaces(Formatter& out, 315 const ComponentSpecificationMessage& /*message*/) { 316 out << "} // namespace vts" << "\n"; 317 out << "} // namespace android" << "\n"; 318 } 319 320 void DriverCodeGenBase::GenerateCodeToStartMeasurement(Formatter& out) { 321 out << "VtsMeasurement vts_measurement;" << "\n"; 322 out << "vts_measurement.Start();" << "\n"; 323 } 324 325 void DriverCodeGenBase::GenerateCodeToStopMeasurement(Formatter& out) { 326 out << "vector<float>* measured = vts_measurement.Stop();" << "\n"; 327 out << "cout << \"time \" << (*measured)[0] << endl;" << "\n"; 328 } 329 330 } // namespace vts 331 } // namespace android 332