Home | History | Annotate | Download | only in driver
      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