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