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