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