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 #define LOG_TAG "VtsHalDriverManager"
     17 
     18 #include "driver_manager/VtsHalDriverManager.h"
     19 
     20 #include <iostream>
     21 #include <string>
     22 
     23 #include <android-base/logging.h>
     24 #include <google/protobuf/text_format.h>
     25 
     26 #include "utils/InterfaceSpecUtil.h"
     27 #include "utils/StringUtil.h"
     28 
     29 static constexpr const char* kErrorString = "error";
     30 static constexpr const char* kVoidString = "void";
     31 static constexpr const int kInvalidDriverId = -1;
     32 
     33 namespace android {
     34 namespace vts {
     35 
     36 VtsHalDriverManager::VtsHalDriverManager(const string& spec_dir,
     37                                          const int epoch_count,
     38                                          const string& callback_socket_name)
     39     : callback_socket_name_(callback_socket_name),
     40       hal_driver_loader_(
     41           HalDriverLoader(spec_dir, epoch_count, callback_socket_name)) {}
     42 
     43 DriverId VtsHalDriverManager::LoadTargetComponent(
     44     const string& dll_file_name, const string& spec_lib_file_path,
     45     const int component_class, const int component_type, const float version,
     46     const string& package_name, const string& component_name,
     47     const string& hw_binder_service_name) {
     48   LOG(DEBUG) << "dll_file_name = " << dll_file_name;
     49   ComponentSpecificationMessage spec_message;
     50   if (!hal_driver_loader_.FindComponentSpecification(
     51           component_class, package_name, version, component_name,
     52           component_type, &spec_message)) {
     53     LOG(ERROR) << "Failed to load specification for component: "
     54                << GetComponentDebugMsg(component_class, component_type,
     55                                        std::to_string(version), package_name,
     56                                        component_name);
     57     return kInvalidDriverId;
     58   }
     59   LOG(INFO) << "Loaded specification for component: "
     60             << GetComponentDebugMsg(component_class, component_type,
     61                                     std::to_string(version), package_name,
     62                                     component_name);
     63 
     64   string driver_lib_path = "";
     65   if (component_class == HAL_HIDL) {
     66     driver_lib_path = GetHidlHalDriverLibName(package_name, version);
     67   } else {
     68     driver_lib_path = spec_lib_file_path;
     69   }
     70 
     71   LOG(DEBUG) << "driver lib path " << driver_lib_path;
     72 
     73   std::unique_ptr<DriverBase> hal_driver = nullptr;
     74   hal_driver.reset(hal_driver_loader_.GetDriver(driver_lib_path, spec_message,
     75                                                 hw_binder_service_name, 0,
     76                                                 false, dll_file_name));
     77   if (!hal_driver) {
     78     LOG(ERROR) << "Can't load driver for component: "
     79                << GetComponentDebugMsg(component_class, component_type,
     80                                        std::to_string(version), package_name,
     81                                        component_name);
     82     return kInvalidDriverId;
     83   } else {
     84     LOG(INFO) << "Loaded driver for component: "
     85               << GetComponentDebugMsg(component_class, component_type,
     86                                       std::to_string(version), package_name,
     87                                       component_name);
     88   }
     89   // TODO (zhuoyao): get hidl_proxy_pointer for loaded hidl hal dirver.
     90   uint64_t interface_pt = 0;
     91   return RegisterDriver(std::move(hal_driver), spec_message, interface_pt);
     92 }
     93 
     94 string VtsHalDriverManager::CallFunction(FunctionCallMessage* call_msg) {
     95   string output = "";
     96   DriverBase* driver = GetDriverWithCallMsg(*call_msg);
     97   if (!driver) {
     98     LOG(ERROR) << "can't find driver for component: "
     99                << GetComponentDebugMsg(
    100                       call_msg->component_class(), call_msg->component_type(),
    101                       call_msg->component_type_version(),
    102                       call_msg->package_name(), call_msg->component_name());
    103     return kErrorString;
    104   }
    105 
    106   FunctionSpecificationMessage* api = call_msg->mutable_api();
    107   void* result;
    108   FunctionSpecificationMessage result_msg;
    109   driver->FunctionCallBegin();
    110   LOG(DEBUG) << "Call Function " << api->name();
    111   if (call_msg->component_class() == HAL_HIDL) {
    112     // Pre-processing if we want to call an API with an interface as argument.
    113     for (int index = 0; index < api->arg_size(); index++) {
    114       auto* arg = api->mutable_arg(index);
    115       if (arg->type() == TYPE_HIDL_INTERFACE) {
    116         string type_name = arg->predefined_type();
    117         ComponentSpecificationMessage spec_msg;
    118         spec_msg.set_package(GetPackageName(type_name));
    119         spec_msg.set_component_type_version(GetVersion(type_name));
    120         spec_msg.set_component_name(GetComponentName(type_name));
    121         DriverId driver_id = FindDriverIdInternal(spec_msg);
    122         // If found a registered driver for the interface, set the pointer in
    123         // the arg proto.
    124         if (driver_id != kInvalidDriverId) {
    125           uint64_t interface_pt = GetDriverPointerById(driver_id);
    126           arg->set_hidl_interface_pointer(interface_pt);
    127         }
    128       }
    129     }
    130     // For Hidl HAL, use CallFunction method.
    131     if (!driver->CallFunction(*api, callback_socket_name_, &result_msg)) {
    132       LOG(ERROR) << "Failed to call function: " << api->DebugString();
    133       return kErrorString;
    134     }
    135   } else {
    136     if (!driver->Fuzz(api, &result, callback_socket_name_)) {
    137       LOG(ERROR) << "Failed to call function: " << api->DebugString();
    138       return kErrorString;
    139     }
    140   }
    141   LOG(DEBUG) << "Called function " << api->name();
    142 
    143   // set coverage data.
    144   driver->FunctionCallEnd(api);
    145 
    146   if (call_msg->component_class() == HAL_HIDL) {
    147     for (int index = 0; index < result_msg.return_type_hidl_size(); index++) {
    148       auto* return_val = result_msg.mutable_return_type_hidl(index);
    149       if (return_val->type() == TYPE_HIDL_INTERFACE) {
    150         if (return_val->hidl_interface_pointer() != 0) {
    151           string type_name = return_val->predefined_type();
    152           uint64_t interface_pt = return_val->hidl_interface_pointer();
    153           std::unique_ptr<DriverBase> driver;
    154           ComponentSpecificationMessage spec_msg;
    155           string package_name = GetPackageName(type_name);
    156           float version = GetVersion(type_name);
    157           string component_name = GetComponentName(type_name);
    158           if (!hal_driver_loader_.FindComponentSpecification(
    159                   HAL_HIDL, package_name, version, component_name, 0,
    160                   &spec_msg)) {
    161             LOG(ERROR)
    162                 << "Failed to load specification for generated interface :"
    163                 << type_name;
    164             return kErrorString;
    165           }
    166           string driver_lib_path =
    167               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         } else {
    177           // in case of generated nullptr, set the driver_id to -1.
    178           return_val->set_hidl_interface_id(-1);
    179         }
    180       }
    181     }
    182     google::protobuf::TextFormat::PrintToString(result_msg, &output);
    183     return output;
    184   } else if (call_msg->component_class() == LIB_SHARED) {
    185     return ProcessFuncResultsForLibrary(api, result);
    186   }
    187   return kVoidString;
    188 }
    189 
    190 bool VtsHalDriverManager::VerifyResults(
    191     DriverId id, const FunctionSpecificationMessage& expected_result,
    192     const FunctionSpecificationMessage& actual_result) {
    193   DriverBase* driver = GetDriverById(id);
    194   if (!driver) {
    195     LOG(ERROR) << "Can't find driver with id: " << id;
    196     return false;
    197   }
    198   return driver->VerifyResults(expected_result, actual_result);
    199 }
    200 
    201 string VtsHalDriverManager::GetAttribute(FunctionCallMessage* call_msg) {
    202   string output = "";
    203   DriverBase* driver = GetDriverWithCallMsg(*call_msg);
    204   if (!driver) {
    205     LOG(ERROR) << "Can't find driver for component: "
    206                << GetComponentDebugMsg(
    207                       call_msg->component_class(), call_msg->component_type(),
    208                       call_msg->component_type_version(),
    209                       call_msg->package_name(), call_msg->component_name());
    210     return kErrorString;
    211   }
    212 
    213   void* result;
    214   FunctionSpecificationMessage* api = call_msg->mutable_api();
    215   LOG(DEBUG) << "Get Atrribute " << api->name() << " parent_path("
    216              << api->parent_path() << ")";
    217   if (!driver->GetAttribute(api, &result)) {
    218     LOG(ERROR) << "attribute not found - todo handle more explicitly";
    219     return kErrorString;
    220   }
    221 
    222   if (call_msg->component_class() == HAL_HIDL) {
    223     api->mutable_return_type()->set_type(TYPE_STRING);
    224     api->mutable_return_type()->mutable_string_value()->set_message(
    225         *(string*)result);
    226     api->mutable_return_type()->mutable_string_value()->set_length(
    227         ((string*)result)->size());
    228     free(result);
    229     string* output = new string();
    230     google::protobuf::TextFormat::PrintToString(*api, output);
    231     return *output;
    232   } else if (call_msg->component_class() == LIB_SHARED) {
    233     return ProcessFuncResultsForLibrary(api, result);
    234   }
    235   return kVoidString;
    236 }
    237 
    238 DriverId VtsHalDriverManager::RegisterDriver(
    239     std::unique_ptr<DriverBase> driver,
    240     const ComponentSpecificationMessage& spec_msg,
    241     const uint64_t interface_pt) {
    242   DriverId driver_id = FindDriverIdInternal(spec_msg, interface_pt, true);
    243   if (driver_id == kInvalidDriverId) {
    244     driver_id = hal_driver_map_.size();
    245     hal_driver_map_.insert(make_pair(
    246         driver_id, HalDriverInfo(spec_msg, interface_pt, std::move(driver))));
    247   } else {
    248     LOG(WARNING) << "Driver already exists. ";
    249   }
    250 
    251   return driver_id;
    252 }
    253 
    254 DriverBase* VtsHalDriverManager::GetDriverById(const DriverId id) {
    255   auto res = hal_driver_map_.find(id);
    256   if (res == hal_driver_map_.end()) {
    257     LOG(ERROR) << "Failed to find driver info with id: " << id;
    258     return nullptr;
    259   }
    260   LOG(DEBUG) << "Found driver info with id: " << id;
    261   return res->second.driver.get();
    262 }
    263 
    264 uint64_t VtsHalDriverManager::GetDriverPointerById(const DriverId id) {
    265   auto res = hal_driver_map_.find(id);
    266   if (res == hal_driver_map_.end()) {
    267     LOG(ERROR) << "Failed to find driver info with id: " << id;
    268     return 0;
    269   }
    270   LOG(DEBUG) << "Found driver info with id: " << id;
    271   return res->second.hidl_hal_proxy_pt;
    272 }
    273 
    274 DriverId VtsHalDriverManager::GetDriverIdForHidlHalInterface(
    275     const string& package_name, const float version,
    276     const string& interface_name, const string& hal_service_name) {
    277   ComponentSpecificationMessage spec_msg;
    278   spec_msg.set_component_class(HAL_HIDL);
    279   spec_msg.set_package(package_name);
    280   spec_msg.set_component_type_version(version);
    281   spec_msg.set_component_name(interface_name);
    282   DriverId driver_id = FindDriverIdInternal(spec_msg);
    283   if (driver_id == kInvalidDriverId) {
    284     string driver_lib_path = GetHidlHalDriverLibName(package_name, version);
    285     driver_id =
    286         LoadTargetComponent("", driver_lib_path, HAL_HIDL, 0, version,
    287                             package_name, interface_name, hal_service_name);
    288   }
    289   return driver_id;
    290 }
    291 
    292 bool VtsHalDriverManager::FindComponentSpecification(
    293     const int component_class, const int component_type, const float version,
    294     const string& package_name, const string& component_name,
    295     ComponentSpecificationMessage* spec_msg) {
    296   return hal_driver_loader_.FindComponentSpecification(
    297       component_class, package_name, version, component_name, component_type,
    298       spec_msg);
    299 }
    300 
    301 ComponentSpecificationMessage*
    302 VtsHalDriverManager::GetComponentSpecification() {
    303   if (hal_driver_map_.empty()) {
    304     return nullptr;
    305   } else {
    306     return &(hal_driver_map_.find(0)->second.spec_msg);
    307   }
    308 }
    309 
    310 DriverId VtsHalDriverManager::FindDriverIdInternal(
    311     const ComponentSpecificationMessage& spec_msg, const uint64_t interface_pt,
    312     bool with_interface_pointer) {
    313   if (!spec_msg.has_component_class()) {
    314     LOG(ERROR) << "Component class not specified. ";
    315     return kInvalidDriverId;
    316   }
    317   if (spec_msg.component_class() == HAL_HIDL) {
    318     if (!spec_msg.has_package() || spec_msg.package().empty()) {
    319       LOG(ERROR) << "Package name is required but not specified.";
    320       return kInvalidDriverId;
    321     }
    322     if (!spec_msg.has_component_type_version()) {
    323       LOG(ERROR) << "Package version is required but not specified.";
    324       return kInvalidDriverId;
    325     }
    326     if (!spec_msg.has_component_name() || spec_msg.component_name().empty()) {
    327       LOG(ERROR) << "Component name is required but not specified.";
    328       return kInvalidDriverId;
    329     }
    330   }
    331   for (auto it = hal_driver_map_.begin(); it != hal_driver_map_.end(); ++it) {
    332     ComponentSpecificationMessage cur_spec_msg = it->second.spec_msg;
    333     if (cur_spec_msg.component_class() != spec_msg.component_class()) {
    334       continue;
    335     }
    336     // If package name is specified, match package name.
    337     if (spec_msg.has_package()) {
    338       if (!cur_spec_msg.has_package() ||
    339           cur_spec_msg.package() != spec_msg.package()) {
    340         continue;
    341       }
    342     }
    343     // If version is specified, match version.
    344     if (spec_msg.has_component_type_version()) {
    345       if (!cur_spec_msg.has_component_type_version() ||
    346           cur_spec_msg.component_type_version() !=
    347               spec_msg.component_type_version()) {
    348         continue;
    349       }
    350     }
    351     if (spec_msg.component_class() == HAL_HIDL) {
    352       if (cur_spec_msg.component_name() != spec_msg.component_name()) {
    353         continue;
    354       }
    355       if (with_interface_pointer &&
    356           it->second.hidl_hal_proxy_pt != interface_pt) {
    357         continue;
    358       }
    359       LOG(DEBUG) << "Found hidl hal driver with id: " << it->first;
    360       return it->first;
    361     } else if (spec_msg.component_class() == LIB_SHARED) {
    362       if (spec_msg.has_component_type() &&
    363           cur_spec_msg.component_type() == spec_msg.component_type()) {
    364         LOG(DEBUG) << "Found shared lib driver with id: " << it->first;
    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     // package_name, version etc.
    382     ComponentSpecificationMessage spec_msg;
    383     spec_msg.set_component_class(call_msg.component_class());
    384     spec_msg.set_package(call_msg.package_name());
    385     spec_msg.set_component_type_version(
    386         stof(call_msg.component_type_version()));
    387     spec_msg.set_component_name(call_msg.component_name());
    388     driver_id = FindDriverIdInternal(spec_msg);
    389   }
    390 
    391   if (driver_id == kInvalidDriverId) {
    392     LOG(ERROR) << "Can't find driver ID for package: "
    393                << call_msg.package_name()
    394                << " version: " << call_msg.component_type_version();
    395     return nullptr;
    396   } else {
    397     return GetDriverById(driver_id);
    398   }
    399 }
    400 
    401 string VtsHalDriverManager::ProcessFuncResultsForLibrary(
    402     FunctionSpecificationMessage* func_msg, void* result) {
    403   string output = "";
    404   if (func_msg->return_type().type() == TYPE_PREDEFINED) {
    405     // TODO: actually handle this case.
    406     if (result != NULL) {
    407       // loads that interface spec and enqueues all functions.
    408       LOG(DEBUG) << "Return type: " << func_msg->return_type().type();
    409     } else {
    410       LOG(ERROR) << "Return value = NULL";
    411     }
    412     LOG(ERROR) << "Todo: support aggregate";
    413     google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    414     return output;
    415   } else if (func_msg->return_type().type() == TYPE_SCALAR) {
    416     // TODO handle when the size > 1.
    417     // todo handle more types;
    418     if (!strcmp(func_msg->return_type().scalar_type().c_str(), "int32_t")) {
    419       func_msg->mutable_return_type()->mutable_scalar_value()->set_int32_t(
    420           *((int*)(&result)));
    421       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    422       return output;
    423     } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
    424                        "uint32_t")) {
    425       func_msg->mutable_return_type()->mutable_scalar_value()->set_uint32_t(
    426           *((int*)(&result)));
    427       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    428       return output;
    429     } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
    430                        "int16_t")) {
    431       func_msg->mutable_return_type()->mutable_scalar_value()->set_int16_t(
    432           *((int*)(&result)));
    433       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    434       return output;
    435     } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
    436                        "uint16_t")) {
    437       google::protobuf::TextFormat::PrintToString(*func_msg, &output);
    438       return output;
    439     }
    440   }
    441   return kVoidString;
    442 }
    443 
    444 string VtsHalDriverManager::GetComponentDebugMsg(const int component_class,
    445                                                  const int component_type,
    446                                                  const string& version,
    447                                                  const string& package_name,
    448                                                  const string& component_name) {
    449   if (component_class == HAL_HIDL) {
    450     return "HIDL_HAL: " + package_name + "@" + version + "::" + component_name;
    451   } else {
    452     return "component_type: " + std::to_string(component_type) +
    453            " version: " + version + " component_name: " + component_name;
    454   }
    455 }
    456 }  // namespace vts
    457 }  // namespace android
    458