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
VtsHalDriverManager(const string & spec_dir,const int epoch_count,const string & callback_socket_name,VtsResourceManager * resource_manager)36 VtsHalDriverManager::VtsHalDriverManager(const string& spec_dir,
37 const int epoch_count,
38 const string& callback_socket_name,
39 VtsResourceManager* resource_manager)
40 : callback_socket_name_(callback_socket_name),
41 hal_driver_loader_(
42 HalDriverLoader(spec_dir, epoch_count, callback_socket_name)),
43 resource_manager_(resource_manager) {}
44
LoadTargetComponent(const string & dll_file_name,const string & spec_lib_file_path,const int component_class,const int component_type,const int version_major,const int version_minor,const string & package_name,const string & component_name,const string & hw_binder_service_name)45 DriverId VtsHalDriverManager::LoadTargetComponent(
46 const string& dll_file_name, const string& spec_lib_file_path,
47 const int component_class, const int component_type,
48 const int version_major, const int version_minor,
49 const string& package_name, const string& component_name,
50 const string& hw_binder_service_name) {
51 LOG(DEBUG) << "dll_file_name = " << dll_file_name;
52 ComponentSpecificationMessage spec_message;
53 if (!hal_driver_loader_.FindComponentSpecification(
54 component_class, package_name, version_major, version_minor,
55 component_name, component_type, &spec_message)) {
56 LOG(ERROR) << "Failed to load specification for component: "
57 << GetComponentDebugMsg(
58 component_class, component_type,
59 GetVersionString(version_major, version_minor),
60 package_name, component_name);
61 return kInvalidDriverId;
62 }
63 LOG(INFO) << "Loaded specification for component: "
64 << GetComponentDebugMsg(
65 component_class, component_type,
66 GetVersionString(version_major, version_minor), package_name,
67 component_name);
68
69 string driver_lib_path = "";
70 if (component_class == HAL_HIDL) {
71 driver_lib_path =
72 GetHidlHalDriverLibName(package_name, version_major, version_minor);
73 } else {
74 driver_lib_path = spec_lib_file_path;
75 }
76
77 LOG(DEBUG) << "driver lib path " << driver_lib_path;
78
79 std::unique_ptr<DriverBase> hal_driver = nullptr;
80 hal_driver.reset(hal_driver_loader_.GetDriver(driver_lib_path, spec_message,
81 hw_binder_service_name, 0,
82 false, dll_file_name));
83 if (!hal_driver) {
84 LOG(ERROR) << "Can't load driver for component: "
85 << GetComponentDebugMsg(
86 component_class, component_type,
87 GetVersionString(version_major, version_minor),
88 package_name, component_name);
89 return kInvalidDriverId;
90 } else {
91 LOG(INFO) << "Loaded driver for component: "
92 << GetComponentDebugMsg(
93 component_class, component_type,
94 GetVersionString(version_major, version_minor),
95 package_name, component_name);
96 }
97 // TODO (zhuoyao): get hidl_proxy_pointer for loaded hidl hal dirver.
98 uint64_t interface_pt = 0;
99 return RegisterDriver(std::move(hal_driver), spec_message, interface_pt);
100 }
101
CallFunction(FunctionCallMessage * call_msg)102 string VtsHalDriverManager::CallFunction(FunctionCallMessage* call_msg) {
103 string output = "";
104 DriverBase* driver = GetDriverWithCallMsg(*call_msg);
105 if (!driver) {
106 LOG(ERROR) << "can't find driver for component: "
107 << GetComponentDebugMsg(
108 call_msg->component_class(), call_msg->component_type(),
109 GetVersionString(
110 call_msg->component_type_version_major(),
111 call_msg->component_type_version_minor()),
112 call_msg->package_name(), call_msg->component_name());
113 return kErrorString;
114 }
115
116 FunctionSpecificationMessage* api = call_msg->mutable_api();
117 void* result;
118 FunctionSpecificationMessage result_msg;
119 driver->FunctionCallBegin();
120 LOG(DEBUG) << "Call Function " << api->name();
121 if (call_msg->component_class() == HAL_HIDL) {
122 // Pre-processing if we want to call an API with an interface as argument.
123 for (int index = 0; index < api->arg_size(); index++) {
124 auto* arg = api->mutable_arg(index);
125 bool process_success = PreprocessHidlHalFunctionCallArgs(arg);
126 if (!process_success) {
127 LOG(ERROR) << "Error in preprocess argument index " << index;
128 return kErrorString;
129 }
130 }
131 // For Hidl HAL, use CallFunction method.
132 if (!driver->CallFunction(*api, callback_socket_name_, &result_msg)) {
133 LOG(ERROR) << "Failed to call function: " << api->DebugString();
134 return kErrorString;
135 }
136 } else {
137 if (!driver->Fuzz(api, &result, callback_socket_name_)) {
138 LOG(ERROR) << "Failed to call function: " << api->DebugString();
139 return kErrorString;
140 }
141 }
142 LOG(DEBUG) << "Called function " << api->name();
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 bool set_success = SetHidlHalFunctionCallResults(return_val);
151 if (!set_success) {
152 LOG(ERROR) << "Error in setting return value index " << index;
153 return kErrorString;
154 }
155 }
156 google::protobuf::TextFormat::PrintToString(result_msg, &output);
157 return output;
158 } else if (call_msg->component_class() == LIB_SHARED) {
159 return ProcessFuncResultsForLibrary(api, result);
160 }
161 return kVoidString;
162 }
163
VerifyResults(DriverId id,const FunctionSpecificationMessage & expected_result,const FunctionSpecificationMessage & actual_result)164 bool VtsHalDriverManager::VerifyResults(
165 DriverId id, const FunctionSpecificationMessage& expected_result,
166 const FunctionSpecificationMessage& actual_result) {
167 DriverBase* driver = GetDriverById(id);
168 if (!driver) {
169 LOG(ERROR) << "Can't find driver with id: " << id;
170 return false;
171 }
172 return driver->VerifyResults(expected_result, actual_result);
173 }
174
GetAttribute(FunctionCallMessage * call_msg)175 string VtsHalDriverManager::GetAttribute(FunctionCallMessage* call_msg) {
176 string output = "";
177 DriverBase* driver = GetDriverWithCallMsg(*call_msg);
178 if (!driver) {
179 LOG(ERROR) << "Can't find driver for component: "
180 << GetComponentDebugMsg(
181 call_msg->component_class(), call_msg->component_type(),
182 GetVersionString(
183 call_msg->component_type_version_major(),
184 call_msg->component_type_version_minor()),
185 call_msg->package_name(), call_msg->component_name());
186 return kErrorString;
187 }
188
189 void* result;
190 FunctionSpecificationMessage* api = call_msg->mutable_api();
191 LOG(DEBUG) << "Get Atrribute " << api->name() << " parent_path("
192 << api->parent_path() << ")";
193 if (!driver->GetAttribute(api, &result)) {
194 LOG(ERROR) << "attribute not found - todo handle more explicitly";
195 return kErrorString;
196 }
197
198 if (call_msg->component_class() == HAL_HIDL) {
199 api->mutable_return_type()->set_type(TYPE_STRING);
200 api->mutable_return_type()->mutable_string_value()->set_message(
201 *(string*)result);
202 api->mutable_return_type()->mutable_string_value()->set_length(
203 ((string*)result)->size());
204 free(result);
205 string* output = new string();
206 google::protobuf::TextFormat::PrintToString(*api, output);
207 return *output;
208 } else if (call_msg->component_class() == LIB_SHARED) {
209 return ProcessFuncResultsForLibrary(api, result);
210 }
211 return kVoidString;
212 }
213
RegisterDriver(std::unique_ptr<DriverBase> driver,const ComponentSpecificationMessage & spec_msg,const uint64_t interface_pt)214 DriverId VtsHalDriverManager::RegisterDriver(
215 std::unique_ptr<DriverBase> driver,
216 const ComponentSpecificationMessage& spec_msg,
217 const uint64_t interface_pt) {
218 DriverId driver_id = FindDriverIdInternal(spec_msg, interface_pt, true);
219 if (driver_id == kInvalidDriverId) {
220 driver_id = hal_driver_map_.size();
221 hal_driver_map_.insert(make_pair(
222 driver_id, HalDriverInfo(spec_msg, interface_pt, std::move(driver))));
223 } else {
224 LOG(WARNING) << "Driver already exists. ";
225 }
226
227 return driver_id;
228 }
229
GetDriverById(const DriverId id)230 DriverBase* VtsHalDriverManager::GetDriverById(const DriverId id) {
231 auto res = hal_driver_map_.find(id);
232 if (res == hal_driver_map_.end()) {
233 LOG(ERROR) << "Failed to find driver info with id: " << id;
234 return nullptr;
235 }
236 LOG(DEBUG) << "Found driver info with id: " << id;
237 return res->second.driver.get();
238 }
239
GetDriverPointerById(const DriverId id)240 uint64_t VtsHalDriverManager::GetDriverPointerById(const DriverId id) {
241 auto res = hal_driver_map_.find(id);
242 if (res == hal_driver_map_.end()) {
243 LOG(ERROR) << "Failed to find driver info with id: " << id;
244 return 0;
245 }
246 LOG(DEBUG) << "Found driver info with id: " << id;
247 return res->second.hidl_hal_proxy_pt;
248 }
249
GetDriverIdForHidlHalInterface(const string & package_name,const int version_major,const int version_minor,const string & interface_name,const string & hal_service_name)250 DriverId VtsHalDriverManager::GetDriverIdForHidlHalInterface(
251 const string& package_name, const int version_major,
252 const int version_minor, const string& interface_name,
253 const string& hal_service_name) {
254 ComponentSpecificationMessage spec_msg;
255 spec_msg.set_component_class(HAL_HIDL);
256 spec_msg.set_package(package_name);
257 spec_msg.set_component_type_version_major(version_major);
258 spec_msg.set_component_type_version_minor(version_minor);
259 spec_msg.set_component_name(interface_name);
260 DriverId driver_id = FindDriverIdInternal(spec_msg);
261 if (driver_id == kInvalidDriverId) {
262 string driver_lib_path =
263 GetHidlHalDriverLibName(package_name, version_major, version_minor);
264 driver_id = LoadTargetComponent("", driver_lib_path, HAL_HIDL, 0,
265 version_major, version_minor, package_name,
266 interface_name, hal_service_name);
267 }
268 return driver_id;
269 }
270
FindComponentSpecification(const int component_class,const int component_type,const int version_major,const int version_minor,const string & package_name,const string & component_name,ComponentSpecificationMessage * spec_msg)271 bool VtsHalDriverManager::FindComponentSpecification(
272 const int component_class, const int component_type,
273 const int version_major, const int version_minor,
274 const string& package_name, const string& component_name,
275 ComponentSpecificationMessage* spec_msg) {
276 return hal_driver_loader_.FindComponentSpecification(
277 component_class, package_name, version_major, version_minor,
278 component_name, component_type, spec_msg);
279 }
280
281 ComponentSpecificationMessage*
GetComponentSpecification()282 VtsHalDriverManager::GetComponentSpecification() {
283 if (hal_driver_map_.empty()) {
284 return nullptr;
285 } else {
286 return &(hal_driver_map_.find(0)->second.spec_msg);
287 }
288 }
289
FindDriverIdInternal(const ComponentSpecificationMessage & spec_msg,const uint64_t interface_pt,bool with_interface_pointer)290 DriverId VtsHalDriverManager::FindDriverIdInternal(
291 const ComponentSpecificationMessage& spec_msg, const uint64_t interface_pt,
292 bool with_interface_pointer) {
293 if (!spec_msg.has_component_class()) {
294 LOG(ERROR) << "Component class not specified. ";
295 return kInvalidDriverId;
296 }
297 if (spec_msg.component_class() == HAL_HIDL) {
298 if (!spec_msg.has_package() || spec_msg.package().empty()) {
299 LOG(ERROR) << "Package name is required but not specified.";
300 return kInvalidDriverId;
301 }
302 if (!spec_msg.has_component_type_version_major() ||
303 !spec_msg.has_component_type_version_minor()) {
304 LOG(ERROR) << "Package version is required but not specified.";
305 return kInvalidDriverId;
306 }
307 if (!spec_msg.has_component_name() || spec_msg.component_name().empty()) {
308 LOG(ERROR) << "Component name is required but not specified.";
309 return kInvalidDriverId;
310 }
311 }
312 for (auto it = hal_driver_map_.begin(); it != hal_driver_map_.end(); ++it) {
313 ComponentSpecificationMessage cur_spec_msg = it->second.spec_msg;
314 if (cur_spec_msg.component_class() != spec_msg.component_class()) {
315 continue;
316 }
317 // If package name is specified, match package name.
318 if (spec_msg.has_package()) {
319 if (!cur_spec_msg.has_package() ||
320 cur_spec_msg.package() != spec_msg.package()) {
321 continue;
322 }
323 }
324 // If version is specified, match version.
325 if (spec_msg.has_component_type_version_major() &&
326 spec_msg.has_component_type_version_minor()) {
327 if (!cur_spec_msg.has_component_type_version_major() ||
328 !cur_spec_msg.has_component_type_version_minor() ||
329 cur_spec_msg.component_type_version_major() !=
330 spec_msg.component_type_version_major() ||
331 cur_spec_msg.component_type_version_minor() !=
332 spec_msg.component_type_version_minor()) {
333 continue;
334 }
335 }
336 if (spec_msg.component_class() == HAL_HIDL) {
337 if (cur_spec_msg.component_name() != spec_msg.component_name()) {
338 continue;
339 }
340 if (with_interface_pointer &&
341 it->second.hidl_hal_proxy_pt != interface_pt) {
342 continue;
343 }
344 LOG(DEBUG) << "Found hidl hal driver with id: " << it->first;
345 return it->first;
346 } else if (spec_msg.component_class() == LIB_SHARED) {
347 if (spec_msg.has_component_type() &&
348 cur_spec_msg.component_type() == spec_msg.component_type()) {
349 LOG(DEBUG) << "Found shared lib driver with id: " << it->first;
350 return it->first;
351 }
352 }
353 }
354 return kInvalidDriverId;
355 }
356
GetDriverWithCallMsg(const FunctionCallMessage & call_msg)357 DriverBase* VtsHalDriverManager::GetDriverWithCallMsg(
358 const FunctionCallMessage& call_msg) {
359 DriverId driver_id = kInvalidDriverId;
360 // If call_mag contains driver_id, use that given driver id.
361 if (call_msg.has_hal_driver_id() &&
362 call_msg.hal_driver_id() != kInvalidDriverId) {
363 driver_id = call_msg.hal_driver_id();
364 } else {
365 // Otherwise, try to find a registed driver matches the given info. e.g.,
366 // package_name, version etc.
367 ComponentSpecificationMessage spec_msg;
368 spec_msg.set_component_class(call_msg.component_class());
369 spec_msg.set_package(call_msg.package_name());
370 spec_msg.set_component_type_version_major(
371 call_msg.component_type_version_major());
372 spec_msg.set_component_type_version_minor(
373 call_msg.component_type_version_minor());
374 spec_msg.set_component_name(call_msg.component_name());
375 driver_id = FindDriverIdInternal(spec_msg);
376 }
377
378 if (driver_id == kInvalidDriverId) {
379 LOG(ERROR) << "Can't find driver ID for package: "
380 << call_msg.package_name() << " version: "
381 << GetVersionString(call_msg.component_type_version_major(),
382 call_msg.component_type_version_minor());
383 return nullptr;
384 } else {
385 return GetDriverById(driver_id);
386 }
387 }
388
ProcessFuncResultsForLibrary(FunctionSpecificationMessage * func_msg,void * result)389 string VtsHalDriverManager::ProcessFuncResultsForLibrary(
390 FunctionSpecificationMessage* func_msg, void* result) {
391 string output = "";
392 if (func_msg->return_type().type() == TYPE_PREDEFINED) {
393 // TODO: actually handle this case.
394 if (result != NULL) {
395 // loads that interface spec and enqueues all functions.
396 LOG(DEBUG) << "Return type: " << func_msg->return_type().type();
397 } else {
398 LOG(ERROR) << "Return value = NULL";
399 }
400 LOG(ERROR) << "Todo: support aggregate";
401 google::protobuf::TextFormat::PrintToString(*func_msg, &output);
402 return output;
403 } else if (func_msg->return_type().type() == TYPE_SCALAR) {
404 // TODO handle when the size > 1.
405 // todo handle more types;
406 if (!strcmp(func_msg->return_type().scalar_type().c_str(), "int32_t")) {
407 func_msg->mutable_return_type()->mutable_scalar_value()->set_int32_t(
408 *((int*)(&result)));
409 google::protobuf::TextFormat::PrintToString(*func_msg, &output);
410 return output;
411 } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
412 "uint32_t")) {
413 func_msg->mutable_return_type()->mutable_scalar_value()->set_uint32_t(
414 *((int*)(&result)));
415 google::protobuf::TextFormat::PrintToString(*func_msg, &output);
416 return output;
417 } else if (!strcmp(func_msg->return_type().scalar_type().c_str(),
418 "int16_t")) {
419 func_msg->mutable_return_type()->mutable_scalar_value()->set_int16_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 "uint16_t")) {
425 google::protobuf::TextFormat::PrintToString(*func_msg, &output);
426 return output;
427 }
428 }
429 return kVoidString;
430 }
431
GetComponentDebugMsg(const int component_class,const int component_type,const string & version,const string & package_name,const string & component_name)432 string VtsHalDriverManager::GetComponentDebugMsg(const int component_class,
433 const int component_type,
434 const string& version,
435 const string& package_name,
436 const string& component_name) {
437 if (component_class == HAL_HIDL) {
438 return "HIDL_HAL: " + package_name + "@" + version + "::" + component_name;
439 } else {
440 return "component_type: " + std::to_string(component_type) +
441 " version: " + version + " component_name: " + component_name;
442 }
443 }
444
PreprocessHidlHalFunctionCallArgs(VariableSpecificationMessage * arg)445 bool VtsHalDriverManager::PreprocessHidlHalFunctionCallArgs(
446 VariableSpecificationMessage* arg) {
447 switch (arg->type()) {
448 case TYPE_ARRAY:
449 case TYPE_VECTOR: {
450 // Recursively parse each element in the vector/array.
451 for (int i = 0; i < arg->vector_size(); i++) {
452 if (!PreprocessHidlHalFunctionCallArgs(arg->mutable_vector_value(i))) {
453 // Bad argument, preprocess failure.
454 LOG(ERROR) << "Failed to preprocess vector value " << i << ".";
455 return false;
456 }
457 }
458 break;
459 }
460 case TYPE_UNION: {
461 // Recursively parse each union value.
462 for (int i = 0; i < arg->union_value_size(); i++) {
463 auto* union_field = arg->mutable_union_value(i);
464 if (!PreprocessHidlHalFunctionCallArgs(union_field)) {
465 // Bad argument, preprocess failure.
466 LOG(ERROR) << "Failed to preprocess union field \""
467 << union_field->name() << "\" in union \"" << arg->name()
468 << "\".";
469 return false;
470 }
471 }
472 break;
473 }
474 case TYPE_STRUCT: {
475 // Recursively parse each struct value.
476 for (int i = 0; i < arg->struct_value_size(); i++) {
477 auto* struct_field = arg->mutable_struct_value(i);
478 if (!PreprocessHidlHalFunctionCallArgs(struct_field)) {
479 // Bad argument, preprocess failure.
480 LOG(ERROR) << "Failed to preprocess struct field \""
481 << struct_field->name() << "\" in struct \"" << arg->name()
482 << "\".";
483 return false;
484 }
485 }
486 break;
487 }
488 case TYPE_REF: {
489 if (!PreprocessHidlHalFunctionCallArgs(arg->mutable_ref_value())) {
490 // Bad argument, preprocess failure.
491 LOG(ERROR) << "Failed to preprocess reference value with name \""
492 << arg->name() << "\".";
493 return false;
494 }
495 break;
496 }
497 case TYPE_HIDL_INTERFACE: {
498 string type_name = arg->predefined_type();
499 ComponentSpecificationMessage spec_msg;
500 string version_str = GetVersion(type_name);
501 int version_major = GetVersionMajor(version_str, true);
502 int version_minor = GetVersionMinor(version_str, true);
503 spec_msg.set_package(GetPackageName(type_name));
504 spec_msg.set_component_type_version_major(version_major);
505 spec_msg.set_component_type_version_minor(version_minor);
506 spec_msg.set_component_name(GetComponentName(type_name));
507 DriverId driver_id = FindDriverIdInternal(spec_msg);
508 // If found a registered driver for the interface, set the pointer in
509 // the arg proto.
510 if (driver_id != kInvalidDriverId) {
511 uint64_t interface_pt = GetDriverPointerById(driver_id);
512 arg->set_hidl_interface_pointer(interface_pt);
513 }
514 break;
515 }
516 case TYPE_FMQ_SYNC:
517 case TYPE_FMQ_UNSYNC: {
518 if (arg->fmq_value_size() == 0) {
519 LOG(ERROR) << "Driver manager: host side didn't specify queue "
520 << "information in fmq_value field.";
521 return false;
522 }
523 if (arg->fmq_value(0).fmq_id() != -1) {
524 // Preprocess an argument that wants to use an existing FMQ.
525 // resource_manager returns address of hidl_memory pointer and
526 // driver_manager fills the address in the proto field,
527 // which can be read by HAL driver.
528 size_t descriptor_addr;
529 bool success =
530 resource_manager_->GetQueueDescAddress(*arg, &descriptor_addr);
531 if (!success) {
532 LOG(ERROR) << "Unable to find queue descriptor for queue with id "
533 << arg->fmq_value(0).fmq_id();
534 return false;
535 }
536 arg->mutable_fmq_value(0)->set_fmq_desc_address(descriptor_addr);
537 }
538 break;
539 }
540 case TYPE_HIDL_MEMORY: {
541 if (arg->hidl_memory_value().mem_id() != -1) {
542 // Preprocess an argument that wants to use an existing hidl_memory.
543 // resource_manager returns the address of the hidl_memory pointer,
544 // and driver_manager fills the address in the proto field,
545 // which can be read by vtsc.
546 size_t hidl_mem_address;
547 bool success =
548 resource_manager_->GetHidlMemoryAddress(*arg, &hidl_mem_address);
549 if (!success) {
550 LOG(ERROR) << "Unable to find hidl_memory with id "
551 << arg->hidl_memory_value().mem_id();
552 return false;
553 }
554 arg->mutable_hidl_memory_value()->set_hidl_mem_address(
555 hidl_mem_address);
556 }
557 break;
558 }
559 case TYPE_HANDLE: {
560 if (arg->handle_value().handle_id() != -1) {
561 // Preprocess an argument that wants to use an existing hidl_handle.
562 // resource_manager returns the address of the hidl_memory pointer,
563 // and driver_manager fills the address in the proto field,
564 // which can be read by vtsc.
565 size_t hidl_handle_address;
566 bool success =
567 resource_manager_->GetHidlHandleAddress(*arg, &hidl_handle_address);
568 if (!success) {
569 LOG(ERROR) << "Unable to find hidl_handle with id "
570 << arg->handle_value().handle_id();
571 return false;
572 }
573 arg->mutable_handle_value()->set_hidl_handle_address(
574 hidl_handle_address);
575 }
576 break;
577 }
578 default:
579 break;
580 }
581 return true;
582 }
583
SetHidlHalFunctionCallResults(VariableSpecificationMessage * return_val)584 bool VtsHalDriverManager::SetHidlHalFunctionCallResults(
585 VariableSpecificationMessage* return_val) {
586 switch (return_val->type()) {
587 case TYPE_ARRAY:
588 case TYPE_VECTOR: {
589 // Recursively set each element in the vector/array.
590 for (int i = 0; i < return_val->vector_size(); i++) {
591 if (!SetHidlHalFunctionCallResults(
592 return_val->mutable_vector_value(i))) {
593 // Failed to set recursive return value.
594 LOG(ERROR) << "Failed to set vector value " << i << ".";
595 return false;
596 }
597 }
598 break;
599 }
600 case TYPE_UNION: {
601 // Recursively set each field.
602 for (int i = 0; i < return_val->union_value_size(); i++) {
603 auto* union_field = return_val->mutable_union_value(i);
604 if (!SetHidlHalFunctionCallResults(union_field)) {
605 // Failed to set recursive return value.
606 LOG(ERROR) << "Failed to set union field \"" << union_field->name()
607 << "\" in union \"" << return_val->name() << "\".";
608 return false;
609 }
610 }
611 break;
612 }
613 case TYPE_STRUCT: {
614 // Recursively set each field.
615 for (int i = 0; i < return_val->struct_value_size(); i++) {
616 auto* struct_field = return_val->mutable_struct_value(i);
617 if (!SetHidlHalFunctionCallResults(struct_field)) {
618 // Failed to set recursive return value.
619 LOG(ERROR) << "Failed to set struct field \"" << struct_field->name()
620 << "\" in struct \"" << return_val->name() << "\".";
621 return false;
622 }
623 }
624 break;
625 }
626 case TYPE_REF: {
627 if (!SetHidlHalFunctionCallResults(return_val->mutable_ref_value())) {
628 // Failed to set recursive return value.
629 LOG(ERROR) << "Failed to set reference value for \""
630 << return_val->name() << "\".";
631 return false;
632 }
633 break;
634 }
635 case TYPE_HIDL_INTERFACE: {
636 if (return_val->hidl_interface_pointer() != 0) {
637 string type_name = return_val->predefined_type();
638 uint64_t interface_pt = return_val->hidl_interface_pointer();
639 std::unique_ptr<DriverBase> driver;
640 ComponentSpecificationMessage spec_msg;
641 string version_str = GetVersion(type_name);
642 int version_major = GetVersionMajor(version_str, true);
643 int version_minor = GetVersionMinor(version_str, true);
644 string package_name = GetPackageName(type_name);
645 string component_name = GetComponentName(type_name);
646 if (!hal_driver_loader_.FindComponentSpecification(
647 HAL_HIDL, package_name, version_major, version_minor,
648 component_name, 0, &spec_msg)) {
649 LOG(ERROR) << "Failed to load specification for generated interface :"
650 << type_name;
651 return false;
652 }
653 string driver_lib_path =
654 GetHidlHalDriverLibName(package_name, version_major, version_minor);
655 // TODO(zhuoyao): figure out a way to get the service_name.
656 string hw_binder_service_name = "default";
657 driver.reset(hal_driver_loader_.GetDriver(driver_lib_path, spec_msg,
658 hw_binder_service_name,
659 interface_pt, true, ""));
660 int32_t driver_id =
661 RegisterDriver(std::move(driver), spec_msg, interface_pt);
662 return_val->set_hidl_interface_id(driver_id);
663 } else {
664 // in case of generated nullptr, set the driver_id to -1.
665 return_val->set_hidl_interface_id(-1);
666 }
667 break;
668 }
669 case TYPE_FMQ_SYNC:
670 case TYPE_FMQ_UNSYNC: {
671 // Tell resource_manager to register a new FMQ.
672 int new_queue_id = resource_manager_->RegisterFmq(*return_val);
673 return_val->mutable_fmq_value(0)->set_fmq_id(new_queue_id);
674 break;
675 }
676 case TYPE_HIDL_MEMORY: {
677 // Tell resource_manager to register the new memory object.
678 int new_mem_id = resource_manager_->RegisterHidlMemory(*return_val);
679 return_val->mutable_hidl_memory_value()->set_mem_id(new_mem_id);
680 break;
681 }
682 case TYPE_HANDLE: {
683 // Tell resource_manager to register the new handle object.
684 int new_handle_id = resource_manager_->RegisterHidlHandle(*return_val);
685 return_val->mutable_handle_value()->set_handle_id(new_handle_id);
686 break;
687 }
688 default:
689 break;
690 }
691 return true;
692 }
693
694 } // namespace vts
695 } // namespace android
696