Home | History | Annotate | Download | only in driver_manager
      1 /*
      2  * Copyright (C) 2017 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 #include "driver_manager/VtsHalDriverManager.h"
     17 
     18 #include <iostream>
     19 #include <string>
     20 
     21 #include <google/protobuf/text_format.h>
     22 
     23 #include "utils/InterfaceSpecUtil.h"
     24 #include "utils/StringUtil.h"
     25 
     26 static constexpr const char* kErrorString = "error";
     27 static constexpr const char* kVoidString = "void";
     28 static constexpr const int kInvalidDriverId = -1;
     29 
     30 namespace android {
     31 namespace vts {
     32 
     33 VtsHalDriverManager::VtsHalDriverManager(const string& spec_dir,
     34                                          const int epoch_count,
     35                                          const string& callback_socket_name)
     36     : callback_socket_name_(callback_socket_name),
     37       default_driver_lib_name_(""),
     38       hal_driver_loader_(
     39           HalDriverLoader(spec_dir, epoch_count, callback_socket_name)) {}
     40 
     41 DriverId VtsHalDriverManager::LoadTargetComponent(
     42     const string& dll_file_name, const string& spec_lib_file_path,
     43     const int component_class, const int component_type, const float version,
     44     const string& package_name, const string& component_name,
     45     const string& hw_binder_service_name, const string& submodule_name) {
     46   cout << __func__ << " entry dll_file_name = " << dll_file_name << endl;
     47   ComponentSpecificationMessage spec_message;
     48   if (!hal_driver_loader_.FindComponentSpecification(
     49           component_class, package_name, version, component_name,
     50           component_type, submodule_name, &spec_message)) {
     51     cerr << __func__ << ": Faild to load specification for component with "
     52          << "class: " << component_class << " type: " << component_type
     53          << " version: " << version << endl;
     54     return kInvalidDriverId;
     55   }
     56   cout << "loaded specification for component with class: " << component_class
     57        << " type: " << component_type << " version: " << version << endl;
     58 
     59   string driver_lib_path = "";
     60   if (component_class == HAL_HIDL) {
     61     driver_lib_path = GetHidlHalDriverLibName(package_name, version);
     62   } else {
     63     driver_lib_path = spec_lib_file_path;
     64     default_driver_lib_name_ = driver_lib_path;
     65   }
     66 
     67   cout << __func__ << " driver lib path " << driver_lib_path << endl;
     68 
     69   std::unique_ptr<DriverBase> hal_driver = nullptr;
     70   hal_driver.reset(hal_driver_loader_.GetDriver(driver_lib_path, spec_message,
     71                                                 hw_binder_service_name, 0,
     72                                                 false, dll_file_name, ""));
     73   if (!hal_driver) {
     74     cerr << "can't load driver for component with class: " << component_class
     75          << " type: " << component_type << " version: " << version << endl;
     76     return kInvalidDriverId;
     77   }
     78 
     79   // TODO (zhuoyao): get hidl_proxy_pointer for loaded hidl hal dirver.
     80   uint64_t interface_pt = 0;
     81   return RegisterDriver(std::move(hal_driver), spec_message, "", interface_pt);
     82 }
     83 
     84 string VtsHalDriverManager::CallFunction(FunctionCallMessage* call_msg) {
     85   string output = "";
     86   DriverBase* driver = GetDriverWithCallMsg(*call_msg);
     87   if (!driver) {
     88     cerr << "can't find driver for package: " << call_msg->package_name()
     89          << " version: " << call_msg->component_type_version() << endl;
     90     return kErrorString;
     91   }
     92 
     93   // Special process to open conventional hal.
     94   FunctionSpecificationMessage* api = call_msg->mutable_api();
     95   if (call_msg->component_class() != HAL_HIDL && api->name() == "#Open") {
     96     cout << __func__ << ":" << __LINE__ << " #Open" << endl;
     97     if (api->arg().size() > 0) {
     98       cout << __func__ << " open conventional hal with arg:"
     99            << api->arg(0).string_value().message() << endl;
    100       driver->OpenConventionalHal(api->arg(0).string_value().message().c_str());
    101     } else {
    102       cout << __func__ << " open conventional hal with no arg" << endl;
    103       driver->OpenConventionalHal();
    104     }
    105     // return the return value from open;
    106     if (api->return_type().has_type()) {
    107       cout << __func__ << " return_type exists" << endl;
    108       // TODO handle when the size > 1.
    109       if (!strcmp(api->return_type().scalar_type().c_str(), "int32_t")) {
    110         cout << __func__ << " return_type is int32_t" << endl;
    111         api->mutable_return_type()->mutable_scalar_value()->set_int32_t(0);
    112         cout << "result " << endl;
    113         // todo handle more types;
    114         google::protobuf::TextFormat::PrintToString(*api, &output);
    115         return output;
    116       }
    117     }
    118     cerr << __func__ << " return_type unknown" << endl;
    119     google::protobuf::TextFormat::PrintToString(*api, &output);
    120     return output;
    121   }
    122 
    123   void* result;
    124   FunctionSpecificationMessage result_msg;
    125   driver->FunctionCallBegin();
    126   cout << __func__ << " Call Function " << api->name() << " parent_path("
    127        << api->parent_path() << ")" << endl;
    128   // For Hidl HAL, use CallFunction method.
    129   if (call_msg->component_class() == HAL_HIDL) {
    130     if (!driver->CallFunction(*api, callback_socket_name_, &result_msg)) {
    131       cerr << __func__ << " Failed to call function: " << api->DebugString()
    132            << endl;
    133       return kErrorString;
    134     }
    135   } else {
    136     if (!driver->Fuzz(api, &result, callback_socket_name_)) {
    137       cerr << __func__ << " Failed to call function: " << api->DebugString()
    138            << endl;
    139       return kErrorString;
    140     }
    141   }
    142   cout << __func__ << ": called function " << api->name() << endl;
    143 
    144   // set coverage data.
    145   driver->FunctionCallEnd(api);
    146 
    147   if (call_msg->component_class() == HAL_HIDL) {
    148     for (int index = 0; index < result_msg.return_type_hidl_size(); index++) {
    149       auto* return_val = result_msg.mutable_return_type_hidl(index);
    150       if (return_val->type() == TYPE_HIDL_INTERFACE &&
    151           return_val->hidl_interface_pointer() != 0) {
    152         string type_name = return_val->predefined_type();
    153         uint64_t interface_pt = return_val->hidl_interface_pointer();
    154         std::unique_ptr<DriverBase> driver;
    155         ComponentSpecificationMessage spec_msg;
    156         string package_name = GetPackageName(type_name);
    157         float version = GetVersion(type_name);
    158         string component_name = GetComponentName(type_name);
    159         if (!hal_driver_loader_.FindComponentSpecification(
    160                 HAL_HIDL, package_name, version, component_name, 0, "",
    161                 &spec_msg)) {
    162           cerr << __func__
    163                << " Failed to load specification for gnerated interface :"
    164                << type_name << endl;
    165           return kErrorString;
    166         }
    167         string driver_lib_path = GetHidlHalDriverLibName(package_name, version);
    168         // TODO(zhuoyao): figure out a way to get the service_name.
    169         string hw_binder_service_name = "default";
    170         driver.reset(hal_driver_loader_.GetDriver(driver_lib_path, spec_msg,
    171                                                   hw_binder_service_name,
    172                                                   interface_pt, true, "", ""));
    173         int32_t driver_id =
    174             RegisterDriver(std::move(driver), spec_msg, "", interface_pt);
    175         return_val->set_hidl_interface_id(driver_id);
    176       }
    177     }
    178     google::protobuf::TextFormat::PrintToString(result_msg, &output);
    179     return output;
    180   } else {
    181     return ProcessFuncResultsForConventionalHal(api, result);
    182   }
    183   return kVoidString;
    184 }
    185 
    186 string VtsHalDriverManager::GetAttribute(FunctionCallMessage* call_msg) {
    187   string output = "";
    188   DriverBase* driver = GetDriverWithCallMsg(*call_msg);
    189   if (!driver) {
    190     cerr << "can't find driver for package: " << call_msg->package_name()
    191          << " version: " << call_msg->component_type_version() << endl;
    192     return kErrorString;
    193   }
    194 
    195   void* result;
    196   FunctionSpecificationMessage* api = call_msg->mutable_api();
    197   cout << __func__ << " Get Atrribute " << api->name() << " parent_path("
    198        << api->parent_path() << ")" << endl;
    199   if (!driver->GetAttribute(api, &result)) {
    200     cerr << __func__ << " attribute not found - todo handle more explicitly"
    201          << endl;
    202     return kErrorString;
    203   }
    204   cout << __func__ << ": called" << endl;
    205 
    206   if (call_msg->component_class() == HAL_HIDL) {
    207     cout << __func__ << ": for a HIDL HAL" << endl;
    208     api->mutable_return_type()->set_type(TYPE_STRING);
    209     api->mutable_return_type()->mutable_string_value()->set_message(
    210         *(string*)result);
    211     api->mutable_return_type()->mutable_string_value()->set_length(
    212         ((string*)result)->size());
    213     free(result);
    214     string* output = new string();
    215     google::protobuf::TextFormat::PrintToString(*api, output);
    216     return *output;
    217   } else {
    218     return ProcessFuncResultsForConventionalHal(api, result);
    219   }
    220   return kVoidString;
    221 }
    222 
    223 DriverId VtsHalDriverManager::RegisterDriver(
    224     std::unique_ptr<DriverBase> driver,
    225     const ComponentSpecificationMessage& spec_msg, const string& submodule_name,
    226     const uint64_t interface_pt) {
    227   DriverId driver_id =
    228       FindDriverIdInternal(spec_msg, submodule_name, interface_pt, true);
    229   if (driver_id == kInvalidDriverId) {
    230     driver_id = hal_driver_map_.size();
    231     hal_driver_map_.insert(
    232         make_pair(driver_id, HalDriverInfo(spec_msg, submodule_name,
    233                                            interface_pt, std::move(driver))));
    234   } else {
    235     cout << __func__ << " Driver already exists. ";
    236   }
    237 
    238   return driver_id;
    239 }
    240 
    241 DriverBase* VtsHalDriverManager::GetDriverById(const int32_t id) {
    242   auto res = hal_driver_map_.find(id);
    243   if (res == hal_driver_map_.end()) {
    244     cerr << "Failed to find driver info with id: " << id << endl;
    245     return nullptr;
    246   }
    247   cout << __func__ << " found driver info with id: " << id << endl;
    248   return res->second.driver.get();
    249 }
    250 
    251 ComponentSpecificationMessage* VtsHalDriverManager::GetComponentSpecById(
    252     const int32_t id) {
    253   auto res = hal_driver_map_.find(id);
    254   if (res == hal_driver_map_.end()) {
    255     cerr << "Failed to find driver info with id: " << id << endl;
    256     return nullptr;
    257   }
    258   cout << __func__ << " found driver info with id: " << id << endl;
    259   return &(res->second.spec_msg);
    260 }
    261 
    262 DriverBase* VtsHalDriverManager::GetDriverForHidlHalInterface(
    263     const string& package_name, const float version,
    264     const string& interface_name, const string& hal_service_name) {
    265   ComponentSpecificationMessage spec_msg;
    266   spec_msg.set_component_class(HAL_HIDL);
    267   spec_msg.set_package(package_name);
    268   spec_msg.set_component_type_version(version);
    269   spec_msg.set_component_name(interface_name);
    270   int32_t driver_id = FindDriverIdInternal(spec_msg);
    271   if (driver_id == kInvalidDriverId) {
    272     string driver_lib_path = GetHidlHalDriverLibName(package_name, version);
    273     driver_id =
    274         LoadTargetComponent("", driver_lib_path, HAL_HIDL, 0, version,
    275                             package_name, interface_name, hal_service_name, "");
    276   }
    277   return GetDriverById(driver_id);
    278 }
    279 
    280 bool VtsHalDriverManager::FindComponentSpecification(
    281     const int component_class, const int component_type, const float version,
    282     const string& submodule_name, const string& package_name,
    283     const string& component_name, ComponentSpecificationMessage* spec_msg) {
    284   return hal_driver_loader_.FindComponentSpecification(
    285       component_class, package_name, version, component_name, component_type,
    286       submodule_name, spec_msg);
    287 }
    288 
    289 ComponentSpecificationMessage*
    290 VtsHalDriverManager::GetComponentSpecification() {
    291   if (hal_driver_map_.empty()) {
    292     return nullptr;
    293   } else {
    294     return &(hal_driver_map_.find(0)->second.spec_msg);
    295   }
    296 }
    297 
    298 DriverId VtsHalDriverManager::FindDriverIdInternal(
    299     const ComponentSpecificationMessage& spec_msg, const string& submodule_name,
    300     const uint64_t interface_pt, bool with_interface_pointer) {
    301   if (!spec_msg.has_component_class()) {
    302     cerr << __func__ << " Component class not specified. " << endl;
    303     return kInvalidDriverId;
    304   }
    305   if (spec_msg.component_class() == HAL_HIDL) {
    306     if (!spec_msg.has_package() || spec_msg.package().empty()) {
    307       cerr << __func__ << " Package name is requried but not specified. "
    308            << endl;
    309       return kInvalidDriverId;
    310     }
    311     if (!spec_msg.has_component_type_version()) {
    312       cerr << __func__ << " Package version is requried but not specified. "
    313            << endl;
    314       return kInvalidDriverId;
    315     }
    316     if (!spec_msg.has_component_name() || spec_msg.component_name().empty()) {
    317       cerr << __func__ << " Component name is requried but not specified. "
    318            << endl;
    319       return kInvalidDriverId;
    320     }
    321   } else {
    322     if (submodule_name.empty()) {
    323       cerr << __func__ << " Submodule name is requried but not specified. "
    324            << endl;
    325       return kInvalidDriverId;
    326     }
    327   }
    328   for (auto it = hal_driver_map_.begin(); it != hal_driver_map_.end(); ++it) {
    329     ComponentSpecificationMessage cur_spec_msg = it->second.spec_msg;
    330     if (cur_spec_msg.component_class() != spec_msg.component_class()) {
    331       continue;
    332     }
    333     // If package name is specified, match package name.
    334     if (spec_msg.has_package()) {
    335       if (!cur_spec_msg.has_package() ||
    336           cur_spec_msg.package() != spec_msg.package()) {
    337         continue;
    338       }
    339     }
    340     // If version is specified, match version.
    341     if (spec_msg.has_component_type_version()) {
    342       if (!cur_spec_msg.has_component_type_version() ||
    343           cur_spec_msg.component_type_version() !=
    344               spec_msg.component_type_version()) {
    345         continue;
    346       }
    347     }
    348     if (spec_msg.component_class() == HAL_HIDL) {
    349       if (cur_spec_msg.component_name() != spec_msg.component_name()) {
    350         continue;
    351       }
    352       if (with_interface_pointer &&
    353           it->second.hidl_hal_proxy_pt != interface_pt) {
    354         continue;
    355       }
    356       cout << __func__ << " Found hidl hal driver with id: " << it->first
    357            << endl;
    358       return it->first;
    359     } else {
    360       if ((!spec_msg.has_component_type() ||
    361            cur_spec_msg.component_type() == spec_msg.component_type()) &&
    362           it->second.submodule_name == submodule_name) {
    363         cout << __func__
    364              << " Found conventional hal driver with id: " << it->first << endl;
    365         return it->first;
    366       }
    367     }
    368   }
    369   return kInvalidDriverId;
    370 }
    371 
    372 DriverBase* VtsHalDriverManager::GetDriverWithCallMsg(
    373     const FunctionCallMessage& call_msg) {
    374   DriverId driver_id = kInvalidDriverId;
    375   // If call_mag contains driver_id, use that given driver id.
    376   if (call_msg.has_hal_driver_id() &&
    377       call_msg.hal_driver_id() != kInvalidDriverId) {
    378     driver_id = call_msg.hal_driver_id();
    379   } else {
    380     // Otherwise, try to find a registed driver matches the given info. e.g.,
    381     // submodule_name, package_name, version etc.
    382     FunctionSpecificationMessage api = call_msg.api();
    383     if (api.submodule_name().size() > 0) {
    384       string submodule_name = api.submodule_name();
    385       cout << __func__ << " submodule name " << submodule_name << endl;
    386       DriverId driver_id = FindDriverIdWithSubModuleName(submodule_name);
    387       if (driver_id != kInvalidDriverId) {
    388         cout << __func__ << " call is for a submodule" << endl;
    389       } else {
    390         cerr << __func__ << " called an API of a non-loaded submodule." << endl;
    391         return nullptr;
    392       }
    393     } else {
    394       ComponentSpecificationMessage spec_msg;
    395       spec_msg.set_component_class(call_msg.component_class());
    396       spec_msg.set_package(call_msg.package_name());
    397       spec_msg.set_component_type_version(
    398           stof(call_msg.component_type_version()));
    399       spec_msg.set_component_name(call_msg.component_name());
    400       driver_id = FindDriverIdInternal(spec_msg);
    401     }
    402   }
    403 
    404   if (driver_id == kInvalidDriverId) {
    405     cerr << "can't find driver ID for package: " << call_msg.package_name()
    406          << " version: " << call_msg.component_type_version() << endl;
    407     return nullptr;
    408   } else {
    409     return GetDriverById(driver_id);
    410   }
    411 }
    412 
    413 DriverId VtsHalDriverManager::FindDriverIdWithSubModuleName(
    414     const string& submodule_name) {
    415   ComponentSpecificationMessage spec_msg;
    416   spec_msg.set_component_class(HAL_CONVENTIONAL);
    417   return FindDriverIdInternal(spec_msg, submodule_name);
    418 }
    419 
    420 string VtsHalDriverManager::ProcessFuncResultsForConventionalHal(
    421     FunctionSpecificationMessage* func_msg, void* result) {
    422   string output = "";
    423   if (func_msg->return_type().type() == TYPE_PREDEFINED) {
    424     // TODO: actually handle this case.
    425     if (result != NULL) {
    426       // loads that interface spec and enqueues all functions.
    427       cout << __func__ << " return type: " << func_msg->return_type().type()
    428            << endl;
    429     } else {
    430       cout << __func__ << " return value = NULL" << endl;
    431     }
    432     cerr << __func__ << " todo: support aggregate" << endl;
    433     google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    434     return output;
    435   } else if (func_msg->return_type().type() == TYPE_SCALAR) {
    436     // TODO handle when the size > 1.
    437     // todo handle more types;
    438     if (!strcmp(func_msg->return_type().scalar_type().c_str(), "int32_t")) {
    439       func_msg->mutable_return_type()->mutable_scalar_value()->set_int32_t(
    440           *((int*)(&result)));
    441       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    442       return output;
    443     } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
    444                        "uint32_t")) {
    445       func_msg->mutable_return_type()->mutable_scalar_value()->set_uint32_t(
    446           *((int*)(&result)));
    447       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    448       return output;
    449     } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
    450                        "int16_t")) {
    451       func_msg->mutable_return_type()->mutable_scalar_value()->set_int16_t(
    452           *((int*)(&result)));
    453       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    454       return output;
    455     } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
    456                        "uint16_t")) {
    457       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    458       return output;
    459     }
    460   } else if (func_msg->return_type().type() == TYPE_SUBMODULE) {
    461     cerr << __func__ << "[driver:hal] return type TYPE_SUBMODULE" << endl;
    462     if (result != NULL) {
    463       // loads that interface spec and enqueues all functions.
    464       cout << __func__ << " return type: " << func_msg->return_type().type()
    465            << endl;
    466     } else {
    467       cout << __func__ << " return value = NULL" << endl;
    468     }
    469     // find a VTS spec for that module
    470     string submodule_name = func_msg->return_type().predefined_type().substr(
    471         0, func_msg->return_type().predefined_type().size() - 1);
    472     ComponentSpecificationMessage submodule_iface_spec_msg;
    473     DriverId driver_id = FindDriverIdWithSubModuleName(submodule_name);
    474     if (driver_id != kInvalidDriverId) {
    475       cout << __func__ << " submodule InterfaceSpecification already loaded"
    476            << endl;
    477       ComponentSpecificationMessage* spec_msg = GetComponentSpecById(driver_id);
    478       func_msg->set_allocated_return_type_submodule_spec(spec_msg);
    479     } else {
    480       // TODO(zhuoyao): under the current assumption, driver_id = 0 means the
    481       // Hal the initially loaded, need to change then when we support
    482       // multi-hal testing.
    483       ComponentSpecificationMessage* spec_msg = GetComponentSpecById(0);
    484       if (hal_driver_loader_.FindComponentSpecification(
    485               spec_msg->component_class(), spec_msg->package(),
    486               spec_msg->component_type_version(), spec_msg->component_name(),
    487               spec_msg->component_type(), submodule_name,
    488               &submodule_iface_spec_msg)) {
    489         cout << __func__ << " submodule InterfaceSpecification found" << endl;
    490         func_msg->set_allocated_return_type_submodule_spec(
    491             &submodule_iface_spec_msg);
    492         std::unique_ptr<DriverBase> driver = nullptr;
    493         driver.reset(hal_driver_loader_.GetDriverForSubModule(
    494             default_driver_lib_name_, submodule_iface_spec_msg, result));
    495         RegisterDriver(std::move(driver), submodule_iface_spec_msg,
    496                        submodule_name, 0);
    497       } else {
    498         cerr << __func__ << " submodule InterfaceSpecification not found"
    499              << endl;
    500       }
    501     }
    502     google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    503     return output;
    504   }
    505   return kVoidString;
    506 }
    507 
    508 }  // namespace vts
    509 }  // namespace android
    510