You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
11 KiB
332 lines
11 KiB
/*
|
|
* Copyright 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "code_gen/driver/DriverCodeGenBase.h"
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include <hidl-util/Formatter.h>
|
|
#include <hidl-util/FQName.h>
|
|
|
|
#include "VtsCompilerUtils.h"
|
|
#include "utils/InterfaceSpecUtil.h"
|
|
#include "utils/StringUtil.h"
|
|
|
|
using namespace std;
|
|
|
|
namespace android {
|
|
namespace vts {
|
|
|
|
void DriverCodeGenBase::GenerateAll(
|
|
Formatter& header_out, Formatter& source_out,
|
|
const ComponentSpecificationMessage& message) {
|
|
GenerateHeaderFile(header_out, message);
|
|
GenerateSourceFile(source_out, message);
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateHeaderFile(
|
|
Formatter& out, const ComponentSpecificationMessage& message) {
|
|
string component_name = GetComponentName(message);
|
|
if (component_name.empty()) {
|
|
cerr << __func__ << ":" << __LINE__ << " error component_name is empty"
|
|
<< "\n";
|
|
exit(-1);
|
|
}
|
|
|
|
string component_name_token;
|
|
if (message.component_class() == HAL_HIDL) {
|
|
FQName component_fq_name = GetFQName(message);
|
|
component_name_token = component_fq_name.tokenName();
|
|
} else {
|
|
string version = GetVersion(message, true);
|
|
component_name_token =
|
|
ComponentClassToString(message.component_class()) + "_" +
|
|
ComponentTypeToString(message.component_type()) + "_" + version;
|
|
}
|
|
string fuzzer_extended_class_name;
|
|
if (message.component_class() == HAL_HIDL) {
|
|
fuzzer_extended_class_name = "FuzzerExtended_" + component_name_token;
|
|
} else {
|
|
fuzzer_extended_class_name = "FuzzerExtended_" + GetComponentName(message);
|
|
}
|
|
|
|
out << "#ifndef __VTS_DRIVER__" << component_name_token << "__\n";
|
|
out << "#define __VTS_DRIVER__" << component_name_token << "__\n";
|
|
out << "\n";
|
|
|
|
out << "#undef LOG_TAG\n";
|
|
out << "#define LOG_TAG \"" << fuzzer_extended_class_name << "\"\n";
|
|
|
|
GenerateHeaderIncludeFiles(out, message, fuzzer_extended_class_name);
|
|
|
|
GenerateOpenNameSpaces(out, message);
|
|
GenerateClassHeader(out, message, fuzzer_extended_class_name);
|
|
out << "\n\n";
|
|
GenerateHeaderGlobalFunctionDeclarations(out, message);
|
|
GenerateCloseNameSpaces(out, message);
|
|
out << "#endif" << "\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateSourceFile(
|
|
Formatter& out, const ComponentSpecificationMessage& message) {
|
|
string component_name = GetComponentName(message);
|
|
if (component_name.empty()) {
|
|
cerr << __func__ << ":" << __LINE__ << " error component_name is empty"
|
|
<< "\n";
|
|
exit(-1);
|
|
}
|
|
FQName component_fq_name = GetFQName(message);
|
|
string component_name_token = component_fq_name.tokenName();
|
|
string fuzzer_extended_class_name;
|
|
if (message.component_class() == HAL_HIDL) {
|
|
fuzzer_extended_class_name = "FuzzerExtended_" + component_name_token;
|
|
} else {
|
|
fuzzer_extended_class_name = "FuzzerExtended_" + GetComponentName(message);
|
|
}
|
|
GenerateSourceIncludeFiles(out, message, fuzzer_extended_class_name);
|
|
out << "\n\n";
|
|
GenerateOpenNameSpaces(out, message);
|
|
GenerateClassImpl(out, message, fuzzer_extended_class_name);
|
|
GenerateCppBodyGlobalFunctions(out, message, fuzzer_extended_class_name);
|
|
GenerateCloseNameSpaces(out, message);
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateClassHeader(Formatter& out,
|
|
const ComponentSpecificationMessage& message,
|
|
const string& fuzzer_extended_class_name) {
|
|
GenerateHeaderInterfaceImpl(out, message);
|
|
out << "class " << fuzzer_extended_class_name << " : public DriverBase {"
|
|
<< "\n";
|
|
out << " public:" << "\n";
|
|
|
|
out.indent();
|
|
GenerateClassConstructionFunction(out, message, fuzzer_extended_class_name);
|
|
GeneratePublicFunctionDeclarations(out, message);
|
|
out.unindent();
|
|
|
|
out << " protected:" << "\n";
|
|
|
|
out.indent();
|
|
out << "bool Fuzz(FunctionSpecificationMessage* func_msg, void** result, "
|
|
<< "const string& callback_socket_name);\n";
|
|
out << "bool CallFunction(const FunctionSpecificationMessage& func_msg, "
|
|
<< "const string& callback_socket_name, "
|
|
<< "FunctionSpecificationMessage* result_msg);\n";
|
|
out << "bool VerifyResults(const FunctionSpecificationMessage& expected_result, "
|
|
<< "const FunctionSpecificationMessage& actual_result);\n";
|
|
out << "bool GetAttribute(FunctionSpecificationMessage* func_msg, "
|
|
<< "void** result);\n";
|
|
|
|
// Produce Fuzz method(s) for sub_struct(s).
|
|
for (auto const& sub_struct : message.interface().sub_struct()) {
|
|
GenerateFuzzFunctionForSubStruct(out, sub_struct, "_");
|
|
}
|
|
// Generate additional function declarations if any.
|
|
GenerateAdditionalFuctionDeclarations(out, message,
|
|
fuzzer_extended_class_name);
|
|
out.unindent();
|
|
|
|
out << " private:" << "\n";
|
|
|
|
out.indent();
|
|
// Generate declarations of private members if any.
|
|
GeneratePrivateMemberDeclarations(out, message);
|
|
out.unindent();
|
|
|
|
out << "};\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateClassImpl(Formatter& out,
|
|
const ComponentSpecificationMessage& message,
|
|
const string& fuzzer_extended_class_name) {
|
|
GenerateCppBodyInterfaceImpl(out, message, fuzzer_extended_class_name);
|
|
GenerateCppBodyFuzzFunction(out, message, fuzzer_extended_class_name);
|
|
GenerateCppBodyGetAttributeFunction(out, message, fuzzer_extended_class_name);
|
|
GenerateDriverFunctionImpl(out, message, fuzzer_extended_class_name);
|
|
GenerateVerificationFunctionImpl(out, message, fuzzer_extended_class_name);
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateHeaderIncludeFiles(Formatter& out,
|
|
const ComponentSpecificationMessage& message, const string&) {
|
|
for (auto const& header : message.header()) {
|
|
out << "#include " << header << "\n";
|
|
}
|
|
out << "\n";
|
|
out << "#include <log/log.h>"
|
|
<< "\n";
|
|
out << "#include <stdarg.h>"
|
|
<< "\n";
|
|
out << "#include <stdio.h>"
|
|
<< "\n";
|
|
out << "#include <stdlib.h>"
|
|
<< "\n";
|
|
out << "#include <string.h>"
|
|
<< "\n";
|
|
out << "\n";
|
|
out << "#include <driver_base/DriverBase.h>"
|
|
<< "\n";
|
|
out << "#include <driver_base/DriverCallbackBase.h>"
|
|
<< "\n";
|
|
out << "\n";
|
|
if (message.component_class() == HAL_HIDL) {
|
|
out << "#include <VtsDriverCommUtil.h>" << "\n";
|
|
out << "\n";
|
|
}
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateSourceIncludeFiles(Formatter& out,
|
|
const ComponentSpecificationMessage& message, const string&) {
|
|
if (message.component_class() != HAL_HIDL) {
|
|
out << "#include \"" << input_vts_file_path_ << ".h\"\n";
|
|
for (auto const& header : message.header()) {
|
|
out << "#include " << header << "\n";
|
|
}
|
|
out << "#include \"vts_datatype.h\"" << "\n";
|
|
} else {
|
|
out << "#include \"" << GetPackagePath(message) << "/"
|
|
<< GetVersion(message) << "/" << GetComponentBaseName(message)
|
|
<< ".vts.h\"\n";
|
|
}
|
|
out << "#include \"vts_measurement.h\"" << "\n";
|
|
out << "#include <android-base/logging.h>"
|
|
<< "\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateHeaderGlobalFunctionDeclarations(
|
|
Formatter& out, const ComponentSpecificationMessage& message,
|
|
const bool print_extern_block) {
|
|
string function_name_prefix = GetFunctionNamePrefix(message);
|
|
|
|
if (print_extern_block) {
|
|
out << "extern \"C\" {" << "\n";
|
|
}
|
|
out << "extern "
|
|
<< "android::vts::DriverBase* " << function_name_prefix << "();\n";
|
|
if (print_extern_block) {
|
|
out << "}" << "\n";
|
|
}
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateCppBodyGlobalFunctions(
|
|
Formatter& out, const ComponentSpecificationMessage& message,
|
|
const string& fuzzer_extended_class_name, const bool print_extern_block) {
|
|
string function_name_prefix = GetFunctionNamePrefix(message);
|
|
|
|
if (print_extern_block) {
|
|
out << "extern \"C\" {" << "\n";
|
|
}
|
|
out << "android::vts::DriverBase* " << function_name_prefix << "() {\n";
|
|
out.indent();
|
|
out << "return (android::vts::DriverBase*) "
|
|
<< "new android::vts::";
|
|
out << fuzzer_extended_class_name << "();\n";
|
|
out.unindent();
|
|
out << "}\n\n";
|
|
if (print_extern_block) {
|
|
out << "}\n";
|
|
}
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateFuzzFunctionForSubStruct(
|
|
Formatter& out, const StructSpecificationMessage& message,
|
|
const string& parent_path) {
|
|
out << "bool Fuzz_" << parent_path << message.name()
|
|
<< "(FunctionSpecificationMessage* func_msg," << "\n";
|
|
out << " void** result, const string& callback_socket_name);"
|
|
<< "\n";
|
|
|
|
out << "bool GetAttribute_" << parent_path << message.name()
|
|
<< "(FunctionSpecificationMessage* /*func_msg*/,"
|
|
<< "\n";
|
|
out << " void** /*result*/);"
|
|
<< "\n";
|
|
|
|
for (auto const& sub_struct : message.sub_struct()) {
|
|
GenerateFuzzFunctionForSubStruct(out, sub_struct,
|
|
parent_path + message.name() + "_");
|
|
}
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateDriverFunctionImpl(Formatter& out,
|
|
const ComponentSpecificationMessage& /*message*/,
|
|
const string& fuzzer_extended_class_name) {
|
|
out << "bool " << fuzzer_extended_class_name
|
|
<< "::CallFunction(const FunctionSpecificationMessage&, const string&, "
|
|
<< "FunctionSpecificationMessage* ) {\n";
|
|
out.indent();
|
|
out << "/* No implementation yet. */\n";
|
|
out << "return true;\n";
|
|
out.unindent();
|
|
out << "}\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateVerificationFunctionImpl(Formatter& out,
|
|
const ComponentSpecificationMessage& /*message*/,
|
|
const string& fuzzer_extended_class_name) {
|
|
out << "bool " << fuzzer_extended_class_name
|
|
<< "::VerifyResults(const FunctionSpecificationMessage&, "
|
|
<< "const FunctionSpecificationMessage&) {\n";
|
|
out.indent();
|
|
out << "/* No implementation yet. */\n";
|
|
out << "return true;\n";
|
|
out.unindent();
|
|
out << "}\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateNamespaceName(
|
|
Formatter& out, const ComponentSpecificationMessage& message) {
|
|
if (message.component_class() == HAL_HIDL && message.has_package()) {
|
|
out << GetPackageNamespaceToken(message)
|
|
<< "::" << GetVersion(message, true);
|
|
} else {
|
|
cerr << __func__ << ":" << __LINE__ << " no namespace" << "\n";
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateOpenNameSpaces(Formatter& out,
|
|
const ComponentSpecificationMessage& message) {
|
|
if (message.component_class() == HAL_HIDL && message.has_package()) {
|
|
out << "using namespace ";
|
|
GenerateNamespaceName(out, message);
|
|
out << ";" << "\n";
|
|
}
|
|
|
|
out << "namespace android {" << "\n";
|
|
out << "namespace vts {" << "\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateCloseNameSpaces(Formatter& out,
|
|
const ComponentSpecificationMessage& /*message*/) {
|
|
out << "} // namespace vts" << "\n";
|
|
out << "} // namespace android" << "\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateCodeToStartMeasurement(Formatter& out) {
|
|
out << "VtsMeasurement vts_measurement;" << "\n";
|
|
out << "vts_measurement.Start();" << "\n";
|
|
}
|
|
|
|
void DriverCodeGenBase::GenerateCodeToStopMeasurement(Formatter& out) {
|
|
out << "vector<float>* measured = vts_measurement.Stop();" << "\n";
|
|
out << "LOG(INFO) << \"time \" << (*measured)[0];"
|
|
<< "\n";
|
|
}
|
|
|
|
} // namespace vts
|
|
} // namespace android
|