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