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 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 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 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 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 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 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 <stdio.h>" << "\n"; 170 out << "#include <stdarg.h>" << "\n"; 171 out << "#include <stdlib.h>" << "\n"; 172 out << "#include <string.h>" << "\n"; 173 out << "#include <utils/Log.h>" << "\n"; 174 out << "\n"; 175 out << "#include <driver_base/DriverBase.h>" 176 << "\n"; 177 out << "#include <driver_base/DriverCallbackBase.h>" 178 << "\n"; 179 out << "\n"; 180 if (message.component_class() == HAL_HIDL) { 181 out << "#include <VtsDriverCommUtil.h>" << "\n"; 182 out << "\n"; 183 } 184 } 185 186 void DriverCodeGenBase::GenerateSourceIncludeFiles(Formatter& out, 187 const ComponentSpecificationMessage& message, const string&) { 188 if (message.component_class() != HAL_HIDL) { 189 out << "#include \"" << input_vts_file_path_ << ".h\"\n"; 190 for (auto const& header : message.header()) { 191 out << "#include " << header << "\n"; 192 } 193 out << "#include \"vts_datatype.h\"" << "\n"; 194 } else { 195 out << "#include \"" << GetPackagePath(message) << "/" 196 << GetVersion(message) << "/" << GetComponentBaseName(message) 197 << ".vts.h\"\n"; 198 } 199 out << "#include \"vts_measurement.h\"" << "\n"; 200 out << "#include <android-base/logging.h>" 201 << "\n"; 202 } 203 204 void DriverCodeGenBase::GenerateHeaderGlobalFunctionDeclarations( 205 Formatter& out, const ComponentSpecificationMessage& message, 206 const bool print_extern_block) { 207 string function_name_prefix = GetFunctionNamePrefix(message); 208 209 if (print_extern_block) { 210 out << "extern \"C\" {" << "\n"; 211 } 212 out << "extern " 213 << "android::vts::DriverBase* " << function_name_prefix << "();\n"; 214 if (print_extern_block) { 215 out << "}" << "\n"; 216 } 217 } 218 219 void DriverCodeGenBase::GenerateCppBodyGlobalFunctions( 220 Formatter& out, const ComponentSpecificationMessage& message, 221 const string& fuzzer_extended_class_name, const bool print_extern_block) { 222 string function_name_prefix = GetFunctionNamePrefix(message); 223 224 if (print_extern_block) { 225 out << "extern \"C\" {" << "\n"; 226 } 227 out << "android::vts::DriverBase* " << function_name_prefix << "() {\n"; 228 out.indent(); 229 out << "return (android::vts::DriverBase*) " 230 << "new android::vts::"; 231 out << fuzzer_extended_class_name << "();\n"; 232 out.unindent(); 233 out << "}\n\n"; 234 if (print_extern_block) { 235 out << "}\n"; 236 } 237 } 238 239 void DriverCodeGenBase::GenerateFuzzFunctionForSubStruct( 240 Formatter& out, const StructSpecificationMessage& message, 241 const string& parent_path) { 242 out << "bool Fuzz_" << parent_path << message.name() 243 << "(FunctionSpecificationMessage* func_msg," << "\n"; 244 out << " void** result, const string& callback_socket_name);" 245 << "\n"; 246 247 out << "bool GetAttribute_" << parent_path << message.name() 248 << "(FunctionSpecificationMessage* /*func_msg*/," 249 << "\n"; 250 out << " void** /*result*/);" 251 << "\n"; 252 253 for (auto const& sub_struct : message.sub_struct()) { 254 GenerateFuzzFunctionForSubStruct(out, sub_struct, 255 parent_path + message.name() + "_"); 256 } 257 } 258 259 void DriverCodeGenBase::GenerateDriverFunctionImpl(Formatter& out, 260 const ComponentSpecificationMessage& /*message*/, 261 const string& fuzzer_extended_class_name) { 262 out << "bool " << fuzzer_extended_class_name 263 << "::CallFunction(const FunctionSpecificationMessage&, const string&, " 264 << "FunctionSpecificationMessage* ) {\n"; 265 out.indent(); 266 out << "/* No implementation yet. */\n"; 267 out << "return true;\n"; 268 out.unindent(); 269 out << "}\n"; 270 } 271 272 void DriverCodeGenBase::GenerateVerificationFunctionImpl(Formatter& out, 273 const ComponentSpecificationMessage& /*message*/, 274 const string& fuzzer_extended_class_name) { 275 out << "bool " << fuzzer_extended_class_name 276 << "::VerifyResults(const FunctionSpecificationMessage&, " 277 << "const FunctionSpecificationMessage&) {\n"; 278 out.indent(); 279 out << "/* No implementation yet. */\n"; 280 out << "return true;\n"; 281 out.unindent(); 282 out << "}\n"; 283 } 284 285 void DriverCodeGenBase::GenerateNamespaceName( 286 Formatter& out, const ComponentSpecificationMessage& message) { 287 if (message.component_class() == HAL_HIDL && message.has_package()) { 288 out << GetPackageNamespaceToken(message) 289 << "::" << GetVersion(message, true); 290 } else { 291 cerr << __func__ << ":" << __LINE__ << " no namespace" << "\n"; 292 exit(-1); 293 } 294 } 295 296 void DriverCodeGenBase::GenerateOpenNameSpaces(Formatter& out, 297 const ComponentSpecificationMessage& message) { 298 if (message.component_class() == HAL_HIDL && message.has_package()) { 299 out << "using namespace "; 300 GenerateNamespaceName(out, message); 301 out << ";" << "\n"; 302 } 303 304 out << "namespace android {" << "\n"; 305 out << "namespace vts {" << "\n"; 306 } 307 308 void DriverCodeGenBase::GenerateCloseNameSpaces(Formatter& out, 309 const ComponentSpecificationMessage& /*message*/) { 310 out << "} // namespace vts" << "\n"; 311 out << "} // namespace android" << "\n"; 312 } 313 314 void DriverCodeGenBase::GenerateCodeToStartMeasurement(Formatter& out) { 315 out << "VtsMeasurement vts_measurement;" << "\n"; 316 out << "vts_measurement.Start();" << "\n"; 317 } 318 319 void DriverCodeGenBase::GenerateCodeToStopMeasurement(Formatter& out) { 320 out << "vector<float>* measured = vts_measurement.Stop();" << "\n"; 321 out << "LOG(INFO) << \"time \" << (*measured)[0];" 322 << "\n"; 323 } 324 325 } // namespace vts 326 } // namespace android 327