1 // 2 // Copyright 2018 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 17 #ifndef __VTS_RESOURCE_VTSRESOURCEMANAGER_H 18 #define __VTS_RESOURCE_VTSRESOURCEMANAGER_H 19 20 #include <android-base/logging.h> 21 #include <android/hardware/audio/4.0/IStreamIn.h> 22 #include <android/hardware/audio/4.0/IStreamOut.h> 23 #include <android/hardware/audio/effect/2.0/types.h> 24 #include <android/hardware/audio/effect/4.0/types.h> 25 #include <google/protobuf/repeated_field.h> 26 #include <google/protobuf/text_format.h> 27 28 #include "fmq_driver/VtsFmqDriver.h" 29 #include "hidl_handle_driver/VtsHidlHandleDriver.h" 30 #include "hidl_memory_driver/VtsHidlMemoryDriver.h" 31 #include "test/vts/proto/ComponentSpecificationMessage.pb.h" 32 #include "test/vts/proto/VtsResourceControllerMessage.pb.h" 33 34 using namespace std; 35 36 namespace android { 37 namespace vts { 38 39 typedef ::android::hardware::audio::V4_0::IStreamIn::ReadParameters 40 ReadParameters; 41 typedef ::android::hardware::audio::V4_0::IStreamIn::ReadStatus ReadStatus; 42 typedef ::android::hardware::audio::V4_0::IStreamOut::WriteCommand WriteCommand; 43 typedef ::android::hardware::audio::V4_0::IStreamOut::WriteStatus WriteStatus; 44 typedef ::android::hardware::audio::effect::V4_0::Result ResultV4_0; 45 typedef ::android::hardware::audio::effect::V2_0::Result ResultV2_0; 46 47 // A class that manages all resources allocated on the target side. 48 // Resources include fast message queue, hidl_memory, hidl_handle. 49 // 50 // Example (Process FMQ Command): 51 // // Initialize a manager. 52 // VtsResourceManager manager; 53 // 54 // // Generate some FMQ request (e.g. creating a queue.). 55 // FmqRequestMessage fmq_request; 56 // fmq_request.set_operation(FMQ_CREATE); 57 // fmq_request.set_data_type("uint16_t"); 58 // fmq_request.set_sync(true); 59 // fmq_request.set_queue_size(2048); 60 // fmq_request.set_blocking(false); 61 // 62 // // receive response. 63 // FmqRequestResponse fmq_response; 64 // // This will ask FMQ driver to process request and send response. 65 // ProcessFmqCommand(fmq_request, &fmq_response); 66 class VtsResourceManager { 67 public: 68 // Constructor to set up the resource manager. 69 VtsResourceManager(); 70 71 // Destructor to clean up the resource manager. 72 ~VtsResourceManager(); 73 74 // Processes command for operations on hidl_handle. 75 // 76 // @param hidl_handle_request contains arguments for the operation. 77 // @param hidl_handle_response to be filled by the function. 78 void ProcessHidlHandleCommand( 79 const HidlHandleRequestMessage& hidl_handle_request, 80 HidlHandleResponseMessage* hidl_handle_response); 81 82 // Registers the handle object in hidl_handle_driver_ given the hidl_handle 83 // address provided in hidl_handle_msg. 84 // 85 // @param hidl_handle_msg stores hidl_handle address, used to find actual 86 // handle object. 87 // 88 // @return handle_id assigned to the new handle object. 89 int RegisterHidlHandle(const VariableSpecificationMessage& hidl_handle_msg); 90 91 // Gets hidl_handle address in hidl_handle_driver_. 92 // If caller wants to use a handle object in the driver, it specifies 93 // handle_id in HandleDataValueMessage. This method calls hidl_handle_driver_ 94 // to locate the handle object with handle_id, and stores the address 95 // in result pointer. 96 // 97 // @param hidl_handle_msg contains handle_id of the handle object. 98 // @param result stores hidl_handle address. 99 // 100 // @return true if the handle object with handle_id is found, and stores 101 // address in result, 102 // false otherwise. 103 bool GetHidlHandleAddress(const VariableSpecificationMessage& hidl_handle_msg, 104 size_t* result); 105 106 // Processes command for operations on hidl_memory. 107 // 108 // @param hidl_memory_request contains arguments for the operation. 109 // @param hidl_memory_response to be filled by the function. 110 void ProcessHidlMemoryCommand( 111 const HidlMemoryRequestMessage& hidl_memory_request, 112 HidlMemoryResponseMessage* hidl_memory_response); 113 114 // Registers the memory object in hidl_memory_driver_ given the hidl_memory 115 // pointer address provided in hidl_memory_msg. 116 // 117 // @param hidl_memory_msg stores hidl_memory pointer, used to find actual 118 // memory pointer. 119 // 120 // @return mem_id assigned to the new memory object. 121 int RegisterHidlMemory(const VariableSpecificationMessage& hidl_memory_msg); 122 123 // Gets hidl_memory pointer address in hidl_memory_driver_. 124 // If caller wants to use a memory object in the driver, it specifies mem_id 125 // in MemoryDataValueMessage. This method calls hidl_memory_driver to locate 126 // the memory object with mem_id, and stores the address in result pointer. 127 // 128 // @param hidl_memory_msg contains memory object mem_id. 129 // @param result stores hidl_memory pointer. 130 // 131 // @return true if the memory object with mem_id is found, and stores pointer 132 // address in result, 133 // false otherwise. 134 bool GetHidlMemoryAddress(const VariableSpecificationMessage& hidl_memory_msg, 135 size_t* result); 136 137 // Processes command for operations on Fast Message Queue. 138 // The arguments are specified in fmq_request, and this function stores result 139 // in fmq_response. 140 // 141 // @param fmq_request contains arguments for the operation. 142 // @param fmq_response to be filled by the function. 143 void ProcessFmqCommand(const FmqRequestMessage& fmq_request, 144 FmqResponseMessage* fmq_response); 145 146 // Registers a fmq in fmq_driver_ given the information provided in 147 // queue_msg. 148 // This message stores queue data_type, sync option, and existing 149 // descriptor address. This method recasts the address into a pointer 150 // and passes it to fmq_driver_. 151 // 152 // @param queue_msg stores queue information, data_type, sync option, 153 // and queue descriptor address. 154 // 155 // @return queue_id assigned to the new queue object. 156 int RegisterFmq(const VariableSpecificationMessage& queue_msg); 157 158 // Gets queue descriptor address specified in VariableSpecificationMessage. 159 // The message contains type of data in the queue, queue flavor, 160 // and queue id. The method calls fmq_driver to locate the address of the 161 // descriptor using these information, then stores the address in 162 // result pointer. 163 // 164 // @param queue_msg contains queue information. 165 // @param result to store queue descriptor pointer address. 166 // 167 // @return true if queue is found and type matches, and stores the descriptor 168 // address in result. 169 // false otherwise. 170 bool GetQueueDescAddress(const VariableSpecificationMessage& queue_msg, 171 size_t* result); 172 173 private: 174 // Function template used in our map that maps type name to function 175 // with template. 176 typedef void (VtsResourceManager::*ProcessFmqCommandFn)( 177 const FmqRequestMessage&, FmqResponseMessage*); 178 179 // This method infers the queue flavor from the sync field in fmq_request 180 // proto message, and calls ProcessFmqCommandInternal() with template T 181 // and queue flavor. 182 // Notice we create another method called 183 // ProcessFmqCommandWithPredefinedType() with the same interface. 184 // This prevents compiler error during conversion between protobuf message 185 // and C++. 186 // 187 // @param fmq_request contains arguments for FMQ operation. 188 // @param fmq_response FMQ response to be filled by this function. 189 template <typename T> 190 void ProcessFmqCommandWithType(const FmqRequestMessage& fmq_request, 191 FmqResponseMessage* fmq_response); 192 193 // A helper method to call methods on fmq_driver. 194 // This method already has the template type and flavor of FMQ. 195 // 196 // @param fmq_request contains arguments for FMQ operation. 197 // @param fmq_response FMQ response to be filled by this function. 198 template <typename T, hardware::MQFlavor flavor> 199 void ProcessFmqCommandInternal(const FmqRequestMessage& fmq_request, 200 FmqResponseMessage* fmq_response); 201 202 // Converts write_data field in fmq_request to a C++ buffer. 203 // For user-defined type, dynamically load the HAL shared library 204 // to parse protobuf message to C++ type. 205 // 206 // @param fmq_request contains the write_data, represented as a repeated 207 // proto field. 208 // @param write_data converted data that will be written into FMQ. 209 // @param write_data_size number of items in write_data. 210 // 211 // @return true if parsing is successful, false otherwise. 212 // This function can fail if loading shared library or locating 213 // function symbols fails in user-defined type. 214 template <typename T> 215 bool FmqProto2Cpp(const FmqRequestMessage& fmq_request, T* write_data, 216 size_t write_data_size); 217 218 // Converts a C++ buffer into read_data field in fmq_response. 219 // For user-defined type, dynamically load the HAL shared library 220 // to parse C++ type to protobuf message. 221 // 222 // @param fmq_response to be filled by the function. The function fills the 223 // read_data field, which is represented as a repeated 224 // proto field. 225 // @param data_type type of data in FMQ, this information will be 226 // written into protobuf message. 227 // @param read_data contains data read from FMQ read operation. 228 // @param read_data_size number of items in read_data. 229 // 230 // @return true if parsing is successful, false otherwise. 231 // This function can fail if loading shared library or locating 232 // function symbols fails in user-defined type. 233 template <typename T> 234 bool FmqCpp2Proto(FmqResponseMessage* fmq_response, const string& data_type, 235 T* read_data, size_t read_data_size); 236 237 // Loads the corresponding HAL driver shared library from the type name. 238 // This function parses the shared library path from a type name, and 239 // loads the shared library object from the path. 240 // 241 // Example: 242 // For type ::android::hardware::audio::V4_0::IStreamIn::ReadParameters, 243 // the path that is parsed from the type name is 244 // /data/local/tmp/android.hardware.audio@4.0-vts.driver.so. 245 // Then the function loads the shared library object from this path. 246 // 247 // TODO: Consider determining the path and bitness by passing a field 248 // in the protobuf message. 249 // 250 // @param data_type type name. 251 // 252 // @return shared library object. 253 void* LoadSharedLibFromTypeName(const string& data_type); 254 255 // Load the translation function between C++ and protobuf. 256 // This method parses the function name that can translate C++ to protobuf 257 // or translate protobuf to C++ from data_type. 258 // Then it loads the function symbol from shared_lib_obj, which is an opened 259 // HAL shared library. 260 // 261 // Example: type name is 262 // ::android::hardware::audio::V4_0::IStreamIn::ReadParameters, 263 // and we have the shared library pointer shared_lib_obj. 264 // To translate from protobuf to C++, we need to call 265 // GetTranslationFuncPtr(shared_lib_obj, data_type, true); 266 // To translate from C++ to protobuf, we need to call 267 // GetTranslationFuncPtr(shared_lib_obj, data_type, false); 268 // 269 // @param shared_lib_obj opened HAL shared library object. 270 // @param data_type type name. 271 // @param is_proto_to_cpp whether the function is to convert proto to C++. 272 // 273 // @return name of the translation function. 274 void* GetTranslationFuncPtr(void* shared_lib_obj, const string& data_type, 275 bool is_proto_to_cpp); 276 277 // Manages Fast Message Queue (FMQ) driver. 278 VtsFmqDriver fmq_driver_; 279 // Manages hidl_memory driver. 280 VtsHidlMemoryDriver hidl_memory_driver_; 281 // Manages hidl_handle driver. 282 VtsHidlHandleDriver hidl_handle_driver_; 283 // A map that maps each FMQ user-defined type into a process 284 // function with template. 285 const unordered_map<string, ProcessFmqCommandFn> func_map_ = { 286 {"int8_t", &VtsResourceManager::ProcessFmqCommandWithType<int8_t>}, 287 {"uint8_t", &VtsResourceManager::ProcessFmqCommandWithType<uint8_t>}, 288 {"int16_t", &VtsResourceManager::ProcessFmqCommandWithType<int16_t>}, 289 {"uint16_t", &VtsResourceManager::ProcessFmqCommandWithType<uint16_t>}, 290 {"int32_t", &VtsResourceManager::ProcessFmqCommandWithType<int32_t>}, 291 {"uint32_t", &VtsResourceManager::ProcessFmqCommandWithType<uint32_t>}, 292 {"int64_t", &VtsResourceManager::ProcessFmqCommandWithType<int64_t>}, 293 {"uint64_t", &VtsResourceManager::ProcessFmqCommandWithType<uint64_t>}, 294 {"float_t", &VtsResourceManager::ProcessFmqCommandWithType<float>}, 295 {"double_t", &VtsResourceManager::ProcessFmqCommandWithType<double>}, 296 {"bool_t", &VtsResourceManager::ProcessFmqCommandWithType<bool>}, 297 {"::android::hardware::audio::V4_0::IStreamIn::ReadParameters", 298 &VtsResourceManager::ProcessFmqCommandWithType<ReadParameters>}, 299 {"::android::hardware::audio::V4_0::IStreamIn::ReadStatus", 300 &VtsResourceManager::ProcessFmqCommandWithType<ReadStatus>}, 301 {"::android::hardware::audio::V4_0::IStreamOut::WriteCommand", 302 &VtsResourceManager::ProcessFmqCommandWithType<WriteCommand>}, 303 {"::android::hardware::audio::effect::V4_0::Result", 304 &VtsResourceManager::ProcessFmqCommandWithType<ResultV4_0>}, 305 {"::android::hardware::audio::effect::V2_0::Result", 306 &VtsResourceManager::ProcessFmqCommandWithType<ResultV2_0>}}; 307 }; 308 309 } // namespace vts 310 } // namespace android 311 #endif //__VTS_RESOURCE_VTSRESOURCEMANAGER_H 312