1 /* 2 * Copyright (C) 2022 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 #ifndef CPP_EVS_SAMPLEDRIVER_AIDL_INCLUDE_CONFIGMANAGER_H 17 #define CPP_EVS_SAMPLEDRIVER_AIDL_INCLUDE_CONFIGMANAGER_H 18 19 #include "ConfigManagerUtil.h" 20 21 #include <aidl/android/hardware/automotive/evs/CameraParam.h> 22 #include <aidl/android/hardware/graphics/common/PixelFormat.h> 23 #include <android-base/logging.h> 24 #include <system/camera_metadata.h> 25 26 #include <tinyxml2.h> 27 28 #include <string> 29 #include <string_view> 30 #include <unordered_map> 31 #include <unordered_set> 32 #include <vector> 33 34 namespace { 35 /* 36 * Please note that this is different from what is defined in 37 * libhardware/modules/camera/3_4/metadata/types.h; this has one additional 38 * field to store a framerate. 39 */ 40 typedef struct { 41 int id; 42 int width; 43 int height; 44 ::aidl::android::hardware::graphics::common::PixelFormat format; 45 int type; 46 int framerate; 47 } StreamConfiguration; 48 49 } // namespace 50 51 class ConfigManager final { 52 public: 53 static std::unique_ptr<ConfigManager> Create(); 54 ConfigManager(const ConfigManager&) = delete; 55 ConfigManager& operator=(const ConfigManager&) = delete; 56 57 /* Camera device's capabilities and metadata */ 58 class CameraInfo { 59 public: CameraInfo()60 CameraInfo() : characteristics(nullptr) {} 61 62 virtual ~CameraInfo(); 63 64 /* Allocate memory for camera_metadata_t */ allocate(size_t entry_cap,size_t data_cap)65 bool allocate(size_t entry_cap, size_t data_cap) { 66 if (characteristics != nullptr) { 67 LOG(ERROR) << "Camera metadata is already allocated"; 68 return false; 69 } 70 71 characteristics = allocate_camera_metadata(entry_cap, data_cap); 72 return characteristics != nullptr; 73 } 74 75 /* 76 * List of supported controls that the primary client can program. 77 * Paraemters are stored with its valid range 78 */ 79 std::unordered_map<::aidl::android::hardware::automotive::evs::CameraParam, 80 std::tuple<int32_t, int32_t, int32_t>> 81 controls; 82 83 /* 84 * List of supported output stream configurations. 85 */ 86 std::unordered_map<int32_t, StreamConfiguration> streamConfigurations; 87 88 /* 89 * Internal storage for camera metadata. Each entry holds a pointer to 90 * data and number of elements 91 */ 92 std::unordered_map<camera_metadata_tag_t, std::pair<void*, size_t>> cameraMetadata; 93 94 /* Camera module characteristics */ 95 camera_metadata_t* characteristics; 96 }; 97 98 class CameraGroupInfo : public CameraInfo { 99 public: CameraGroupInfo()100 CameraGroupInfo() {} 101 102 /* ID of member camera devices */ 103 std::unordered_set<std::string> devices; 104 105 /* The capture operation of member camera devices are synchronized */ 106 int32_t synchronized = 0; 107 }; 108 109 class SystemInfo { 110 public: 111 /* number of available cameras */ 112 int32_t numCameras = 0; 113 }; 114 115 class DisplayInfo { 116 public: 117 /* 118 * List of supported input stream configurations. 119 */ 120 std::unordered_map<int32_t, StreamConfiguration> streamConfigurations; 121 }; 122 123 /* 124 * Return system information 125 * 126 * @return SystemInfo 127 * Constant reference of SystemInfo. 128 */ getSystemInfo()129 const SystemInfo& getSystemInfo() { 130 std::unique_lock<std::mutex> lock(mConfigLock); 131 mConfigCond.wait(lock, [this] { return mIsReady; }); 132 return mSystemInfo; 133 } 134 135 /* 136 * Return a list of camera identifiers 137 * 138 * This function assumes that it is not being called frequently. 139 * 140 * @return std::vector<std::string> 141 * A vector that contains unique camera device identifiers. 142 */ getCameraIdList()143 std::vector<std::string> getCameraIdList() { 144 std::unique_lock<std::mutex> lock(mConfigLock); 145 mConfigCond.wait(lock, [this] { return mIsReady; }); 146 147 std::vector<std::string> aList; 148 for (auto&& v : mCameraInfo) { 149 aList.push_back(v.first); 150 } 151 152 return aList; 153 } 154 155 /* 156 * Return a list of camera group identifiers 157 * 158 * This function assumes that it is not being called frequently. 159 * 160 * @return std::vector<std::string> 161 * A vector that contains unique camera device identifiers. 162 */ getCameraGroupIdList()163 std::vector<std::string> getCameraGroupIdList() { 164 std::unique_lock<std::mutex> lock(mConfigLock); 165 mConfigCond.wait(lock, [this] { return mIsReady; }); 166 167 std::vector<std::string> aList; 168 for (auto&& v : mCameraGroups) { 169 aList.push_back(v.first); 170 } 171 172 return aList; 173 } 174 175 /* 176 * Return a pointer to the camera group 177 * 178 * @return CameraGroup 179 * A pointer to a camera group identified by a given id. 180 */ getCameraGroupInfo(const std::string & gid)181 std::unique_ptr<CameraGroupInfo>& getCameraGroupInfo(const std::string& gid) { 182 std::unique_lock<std::mutex> lock(mConfigLock); 183 mConfigCond.wait(lock, [this] { return mIsReady; }); 184 185 return mCameraGroups[gid]; 186 } 187 188 /* 189 * Return a camera metadata 190 * 191 * @param cameraId 192 * Unique camera node identifier in string 193 * 194 * @return unique_ptr<CameraInfo> 195 * A pointer to CameraInfo that is associated with a given camera 196 * ID. This returns a null pointer if this does not recognize a 197 * given camera identifier. 198 */ getCameraInfo(const std::string cameraId)199 std::unique_ptr<CameraInfo>& getCameraInfo(const std::string cameraId) noexcept { 200 std::unique_lock<std::mutex> lock(mConfigLock); 201 mConfigCond.wait(lock, [this] { return mIsReady; }); 202 203 return mCameraInfo[cameraId]; 204 } 205 206 /* 207 * Tell whether the configuration data is ready to be used 208 * 209 * @return bool 210 * True if configuration data is ready to be consumed. 211 */ isReady()212 bool isReady() const { return mIsReady; } 213 214 private: 215 /* Constructors */ ConfigManager()216 ConfigManager() : mBinaryFilePath("") {} 217 218 static std::string_view sConfigDefaultPath; 219 static std::string_view sConfigOverridePath; 220 221 /* System configuration */ 222 SystemInfo mSystemInfo; 223 224 /* Internal data structure for camera device information */ 225 std::unordered_map<std::string, std::unique_ptr<CameraInfo>> mCameraInfo; 226 227 /* Internal data structure for camera device information */ 228 std::unordered_map<std::string, std::unique_ptr<DisplayInfo>> mDisplayInfo; 229 230 /* Camera groups are stored in <groud id, CameraGroup> hash map */ 231 std::unordered_map<std::string, std::unique_ptr<CameraGroupInfo>> mCameraGroups; 232 233 /* 234 * Camera positions are stored in <position, camera id set> hash map. 235 * The position must be one of front, rear, left, and right. 236 */ 237 std::unordered_map<std::string, std::unordered_set<std::string>> mCameraPosition; 238 239 /* Configuration data lock */ 240 mutable std::mutex mConfigLock; 241 242 /* 243 * This condition is signalled when it completes a configuration data 244 * preparation. 245 */ 246 std::condition_variable mConfigCond; 247 248 /* A path to a binary configuration file */ 249 const char* mBinaryFilePath; 250 251 /* Configuration data readiness */ 252 bool mIsReady = false; 253 254 /* 255 * Parse a given EVS configuration file and store the information 256 * internally. 257 * 258 * @return bool 259 * True if it completes parsing a file successfully. 260 */ 261 bool readConfigDataFromXML() noexcept; 262 263 /* 264 * read the information of the vehicle 265 * 266 * @param aSysElem 267 * A pointer to "system" XML element. 268 */ 269 void readSystemInfo(const tinyxml2::XMLElement* const aSysElem); 270 271 /* 272 * read the information of camera devices 273 * 274 * @param aCameraElem 275 * A pointer to "camera" XML element that may contain multiple 276 * "device" elements. 277 */ 278 void readCameraInfo(const tinyxml2::XMLElement* const aCameraElem); 279 280 /* 281 * read display device information 282 * 283 * @param aDisplayElem 284 * A pointer to "display" XML element that may contain multiple 285 * "device" elements. 286 */ 287 void readDisplayInfo(const tinyxml2::XMLElement* const aDisplayElem); 288 289 /* 290 * read camera device information 291 * 292 * @param aCamera 293 * A pointer to CameraInfo that will be completed by this 294 * method. 295 * aDeviceElem 296 * A pointer to "device" XML element that contains camera module 297 * capability info and its characteristics. 298 * 299 * @return bool 300 * Return false upon any failure in reading and processing camera 301 * device information. 302 */ 303 bool readCameraDeviceInfo(CameraInfo* aCamera, const tinyxml2::XMLElement* aDeviceElem); 304 305 /* 306 * read camera metadata 307 * 308 * @param aCapElem 309 * A pointer to "cap" XML element. 310 * @param aCamera 311 * A pointer to CameraInfo that is being filled by this method. 312 * @param dataSize 313 * Required size of memory to store camera metadata found in this 314 * method. This is calculated in this method and returned to the 315 * caller for camera_metadata allocation. 316 * 317 * @return size_t 318 * Number of camera metadata entries 319 */ 320 size_t readCameraCapabilities(const tinyxml2::XMLElement* const aCapElem, CameraInfo* aCamera, 321 size_t& dataSize); 322 323 /* 324 * read camera metadata 325 * 326 * @param aParamElem 327 * A pointer to "characteristics" XML element. 328 * @param aCamera 329 * A pointer to CameraInfo that is being filled by this method. 330 * @param dataSize 331 * Required size of memory to store camera metadata found in this 332 * method. 333 * 334 * @return size_t 335 * Number of camera metadata entries 336 */ 337 size_t readCameraMetadata(const tinyxml2::XMLElement* const aParamElem, CameraInfo* aCamera, 338 size_t& dataSize); 339 340 /* 341 * construct camera_metadata_t from camera capabilities and metadata 342 * 343 * @param aCamera 344 * A pointer to CameraInfo that is being filled by this method. 345 * @param totalEntries 346 * Number of camera metadata entries to be added. 347 * @param totalDataSize 348 * Sum of sizes of camera metadata entries to be added. 349 * 350 * @return bool 351 * False if either it fails to allocate memory for camera metadata 352 * or its size is not large enough to add all found camera metadata 353 * entries. 354 */ 355 bool constructCameraMetadata(CameraInfo* aCamera, const size_t totalEntries, 356 const size_t totalDataSize); 357 358 /* 359 * Read configuration data from the binary file 360 * 361 * @return bool 362 * True if it succeeds to read configuration data from a binary 363 * file. 364 */ 365 bool readConfigDataFromBinary(); 366 367 /* 368 * Store configuration data to the file 369 * 370 * @return bool 371 * True if it succeeds to serialize mCameraInfo to the file. 372 */ 373 bool writeConfigDataToBinary(); 374 375 /* 376 * debugging method to print out all XML elements and their attributes in 377 * logcat message. 378 * 379 * @param aNode 380 * A pointer to the root XML element to navigate. 381 * @param prefix 382 * A prefix to XML string. 383 */ 384 void printElementNames(const tinyxml2::XMLElement* aNode, std::string prefix = "") const; 385 }; 386 #endif // CPP_EVS_SAMPLEDRIVER_AIDL_INCLUDE_CONFIGMANAGER_H 387